├── .gitignore ├── doc └── 锐捷认证过程分析与第三方锐捷认证客户端的设计与实现.pdf ├── src ├── mentohust_encryption │ ├── CMakeLists.txt │ ├── types.h │ ├── mento_myfun.h │ ├── mentohustV4.h │ ├── rjmd5.h │ ├── rjsha1.h │ ├── ustd.h │ ├── rjtiger.h │ ├── rjwhirlpool.h │ ├── rjripemd128.h │ ├── mento_myfun.c │ ├── mento_md5.h │ ├── ampheck.h │ ├── md5.h │ ├── byte_order.c.orig │ ├── rjsha1.c │ ├── byte_order.c │ ├── byte_order.h │ ├── rjtiger.c │ ├── rjwhirlpool.c │ ├── rjmd5.c │ ├── mento_md5.c │ ├── rjripemd128.c │ ├── md5.c │ └── rjtiger_sbox.c ├── CMakeLists.txt ├── eap_frames_operations.h ├── functions.h ├── init.h ├── construct_eap_frames.h ├── main.c ├── eap_frames_operations.c ├── functions.c └── init.c ├── CMakeLists.txt ├── cmake └── Modules │ ├── FindPCAP.cmake │ └── FindIconv.cmake ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /doc/锐捷认证过程分析与第三方锐捷认证客户端的设计与实现.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShanQincheng/jmuSupplicant/HEAD/doc/锐捷认证过程分析与第三方锐捷认证客户端的设计与实现.pdf -------------------------------------------------------------------------------- /src/mentohust_encryption/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | AUX_SOURCE_DIRECTORY("." MENTOHUST_ENCRYPTION_SRCS) 2 | SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}/bin") 3 | SET(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/lib") 4 | ADD_LIBRARY("mentohust_encryption" ${MENTOHUST_ENCRYPTION_SRCS}) -------------------------------------------------------------------------------- /src/mentohust_encryption/types.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPES_H 2 | #define TYPES_H 3 | typedef unsigned char *POINTER; 4 | typedef unsigned char BYTE; 5 | typedef unsigned char UCHAR; 6 | typedef unsigned short int WORD; 7 | typedef int LONG; 8 | typedef unsigned int DWORD; 9 | typedef unsigned int UINT4; 10 | #endif 11 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | AUX_SOURCE_DIRECTORY("." JMUSUPPLICANT_SRCS) 2 | ADD_SUBDIRECTORY("mentohust_encryption") 3 | SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}/bin") 4 | SET(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/lib") 5 | ADD_EXECUTABLE("jmusupplicant" ${JMUSUPPLICANT_SRCS}) 6 | TARGET_LINK_LIBRARIES(jmusupplicant ${PCAP_LIBRARY} ${ICONV_LIBRARY} "mentohust_encryption") -------------------------------------------------------------------------------- /src/mentohust_encryption/mento_myfun.h: -------------------------------------------------------------------------------- 1 | #ifndef MENTO_MYFUN_ 2 | #define MENTO_MYFUN_ 3 | 4 | #include 5 | #include 6 | 7 | 8 | extern void getEchoKey(const uint8_t *capBuf); 9 | static u_char encode(u_char base); /* 算法,将一个字节的8位颠倒并取反 */ 10 | extern void fillEchoPacket(uint8_t *echoBuf); 11 | static u_char encode(u_char base); /* 算法,将一个字节的8位颠倒并取反 */ 12 | extern u_char *encodeIP(u_int32_t ip); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 | PROJECT(jmusupplicant) 3 | IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 4 | SET( USE_ICONV ON ) 5 | ENDIF() 6 | SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/") 7 | SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}/bin") 8 | SET(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/lib") 9 | SET(LIBGIT2_PC_LIBS "") 10 | SET(LIBGIT2_PC_REQUIRES "") 11 | IF (USE_ICONV) 12 | FIND_PACKAGE(ICONV REQUIRED) 13 | ENDIF() 14 | FIND_PACKAGE(PCAP REQUIRED) 15 | ADD_SUBDIRECTORY("src") -------------------------------------------------------------------------------- /src/mentohust_encryption/mentohustV4.h: -------------------------------------------------------------------------------- 1 | #ifndef MENTOHUSTV4_ 2 | #define MENTOHUSTV4_ 3 | 4 | #include 5 | #include 6 | 7 | #include "rjwhirlpool.h" 8 | #include "rjtiger.h" 9 | #include "rjripemd128.h" 10 | #include "rjsha1.h" 11 | #include "rjmd5.h" 12 | #include "md5.h" 13 | #include "mento_md5.h" 14 | #include "../construct_eap_frames.h" 15 | 16 | #define md5_block_size 64 17 | 18 | 19 | extern unsigned char *computeV4(const unsigned char *src, int len); 20 | extern char *computePwd(const unsigned char *md5); 21 | extern u_char *checkPass(u_char id, const u_char *md5Seed, int seedLen); 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/mentohust_encryption/rjmd5.h: -------------------------------------------------------------------------------- 1 | /* md5.h */ 2 | #ifndef MD5_HIDER 3 | #define MD5_HIDER 4 | #include "ustd.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #define md5_block_size 64 11 | #define md5_hash_size 16 12 | 13 | /* algorithm context */ 14 | typedef struct md5_ctx { 15 | unsigned message[md5_block_size / 4]; /* 512-bit buffer for leftovers */ 16 | uint64_t length; /* number of processed bytes */ 17 | unsigned hash[4]; /* 128-bit algorithm internal hashing state */ 18 | } md5_ctx; 19 | 20 | /* hash functions */ 21 | 22 | void rhash_md5_init(md5_ctx *ctx); 23 | void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size); 24 | void rhash_md5_final(md5_ctx *ctx, unsigned char result[16]); 25 | 26 | #ifdef __cplusplus 27 | } /* extern "C" */ 28 | #endif /* __cplusplus */ 29 | 30 | #endif /* MD5_HIDER */ -------------------------------------------------------------------------------- /src/mentohust_encryption/rjsha1.h: -------------------------------------------------------------------------------- 1 | /* sha1.h */ 2 | #ifndef SHA1_H 3 | #define SHA1_H 4 | #include "ustd.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #define sha1_block_size 64 11 | #define sha1_hash_size 20 12 | 13 | /* algorithm context */ 14 | typedef struct sha1_ctx { 15 | unsigned char message[sha1_block_size]; /* 512-bit buffer for leftovers */ 16 | uint64_t length; /* number of processed bytes */ 17 | unsigned hash[5]; /* 160-bit algorithm internal hashing state */ 18 | } sha1_ctx; 19 | 20 | /* hash functions */ 21 | 22 | void rhash_sha1_init(sha1_ctx *ctx); 23 | void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size); 24 | void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result); 25 | 26 | #ifdef __cplusplus 27 | } /* extern "C" */ 28 | #endif /* __cplusplus */ 29 | 30 | #endif /* SHA1_H */ -------------------------------------------------------------------------------- /src/mentohust_encryption/ustd.h: -------------------------------------------------------------------------------- 1 | /* ustd.h common macros and includes */ 2 | #ifndef LIBRHASH_USTD_H 3 | #define LIBRHASH_USTD_H 4 | 5 | #if _MSC_VER >= 1300 6 | 7 | # define int64_t __int64 8 | # define int32_t __int32 9 | # define int16_t __int16 10 | # define int8_t __int8 11 | # define uint64_t unsigned __int64 12 | # define uint32_t unsigned __int32 13 | # define uint16_t unsigned __int16 14 | # define uint8_t unsigned __int8 15 | 16 | /* disable warnings: The POSIX name for this item is deprecated. Use the ISO C++ conformant name. */ 17 | #pragma warning(disable : 4996) 18 | 19 | #else /* _MSC_VER >= 1300 */ 20 | 21 | # include 22 | # include 23 | 24 | #endif /* _MSC_VER >= 1300 */ 25 | 26 | #if _MSC_VER <= 1300 27 | # include /* size_t for vc6.0 */ 28 | #endif /* _MSC_VER <= 1300 */ 29 | 30 | #endif /* LIBRHASH_USTD_H */ 31 | -------------------------------------------------------------------------------- /src/mentohust_encryption/rjtiger.h: -------------------------------------------------------------------------------- 1 | /* tiger.h */ 2 | #ifndef TIGER_H 3 | #define TIGER_H 4 | #include "ustd.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #define tiger_block_size 64 11 | #define tiger_hash_length 24 12 | 13 | /* algorithm context */ 14 | typedef struct tiger_ctx { 15 | /* the order of the fields slightly influence the algorithm speed */ 16 | uint64_t hash[3]; /* algorithm 192-bit state */ 17 | unsigned char message[tiger_block_size]; /* 512-bit buffer for leftovers */ 18 | uint64_t length; /* processed message length */ 19 | int tiger2; /* flag, 1 for Tiger2 algorithm, default is 0 */ 20 | } tiger_ctx; 21 | 22 | /* hash functions */ 23 | 24 | void rhash_tiger_init(tiger_ctx *ctx); 25 | void rhash_tiger_update(tiger_ctx *ctx, const unsigned char* msg, size_t size); 26 | void rhash_tiger_final(tiger_ctx *ctx, unsigned char result[24]); 27 | 28 | #ifdef __cplusplus 29 | } /* extern "C" */ 30 | #endif /* __cplusplus */ 31 | 32 | #endif /* TIGER_H */ 33 | -------------------------------------------------------------------------------- /src/mentohust_encryption/rjwhirlpool.h: -------------------------------------------------------------------------------- 1 | /* whirlpool.h */ 2 | #ifndef WHIRLPOOL_H 3 | #define WHIRLPOOL_H 4 | #include "ustd.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #define whirlpool_block_size 64 11 | 12 | /* algorithm context */ 13 | typedef struct whirlpool_ctx { 14 | uint64_t hash[8]; /* 512-bit algorithm internal hashing state */ 15 | unsigned char message[whirlpool_block_size]; /* 512-bit buffer to hash */ 16 | 17 | /* Note: original algorith uses 256-bit counter, allowing to hash up to 18 | 2^256 bits sized message. For optimization we use here 64-bit counter, 19 | thus reducing maximal message size to 2^64 bits = 2 Exbibytes = 2^21 TiB) */ 20 | uint64_t length; /* number of processed bytes */ 21 | } whirlpool_ctx; 22 | 23 | /* hash functions */ 24 | 25 | void rhash_whirlpool_init(whirlpool_ctx* ctx); 26 | void rhash_whirlpool_update(whirlpool_ctx* ctx, const unsigned char* msg, size_t size); 27 | void rhash_whirlpool_final(whirlpool_ctx* ctx, unsigned char* result); 28 | 29 | #ifdef __cplusplus 30 | } /* extern "C" */ 31 | #endif /* __cplusplus */ 32 | 33 | #endif /* WHIRLPOOL_H */ 34 | -------------------------------------------------------------------------------- /src/eap_frames_operations.h: -------------------------------------------------------------------------------- 1 | #ifndef EAP_FRAMES_OPERATIONS_ 2 | #define EAP_FRAMES_OPERATIONS_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "construct_eap_frames.h" 13 | #include "functions.h" 14 | 15 | #define DEBUG 1 16 | 17 | typedef enum { 18 | EAPOL_START = 0, 19 | EAP_REQUEST_IDENTITY, 20 | EAP_REQUEST_MD5_CHALLENGE, 21 | EAPOL_LOGOFF, 22 | EAP_FAILURE, 23 | EAP_SUCCESS, 24 | ONLINE, 25 | 26 | ERROR 27 | } SEND_FRAME_TYPE; 28 | 29 | const static unsigned SNAP_LENGTH = 2048; // snapshot length 30 | //const static unsigned EAP_ID_ADDRESS = 0x13; // eap id address in EAP-IDENTITY frame 31 | 32 | int capture_eap_frames(); 33 | static void determine_eap_frame_type_then_response_eap_frame(u_char *args, const struct pcap_pkthdr* header, const uint8_t *frame); 34 | int send_eap_frame(SEND_FRAME_TYPE type, const uint8_t *frame); 35 | 36 | static void type_req_idnty_action(const uint8_t *frame); 37 | static void type_req_md5_chg_action(const uint8_t *frame); 38 | static void type_failure_action(const uint8_t *frame); 39 | static void type_success_action(const uint8_t *frame); 40 | static void type_error_action(); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/mentohust_encryption/rjripemd128.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Copyright (C) 2009 Gabriel A. Petursson 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef ampheck_ripemd128_h 20 | #define ampheck_ripemd128_h 21 | 22 | #include 23 | #include 24 | 25 | struct ampheck_ripemd128 { 26 | uint32_t h[4]; 27 | uint8_t buffer[64]; 28 | 29 | uint64_t length; 30 | }; 31 | 32 | void ampheck_ripemd128_init(struct ampheck_ripemd128 *ctx); 33 | void ampheck_ripemd128_update(struct ampheck_ripemd128 *ctx, const uint8_t *data, size_t length); 34 | void ampheck_ripemd128_finish(const struct ampheck_ripemd128 *ctx, uint8_t *digest); 35 | 36 | #endif -------------------------------------------------------------------------------- /src/mentohust_encryption/mento_myfun.c: -------------------------------------------------------------------------------- 1 | #include "mento_myfun.h" 2 | 3 | static u_int32_t echoKey = 0, echoNo = 0x0000102B; /* Echo阶段所需 */ 4 | 5 | void fillEchoPacket(uint8_t *echoBuf) 6 | { 7 | int i; 8 | u_int32_t dd1=htonl(echoKey + echoNo), dd2=htonl(echoNo); 9 | u_char *bt1=(u_char *)&dd1, *bt2=(u_char *)&dd2; 10 | echoNo++; 11 | for (i=0; i<4; i++) { 12 | echoBuf[0x18+i] = encode(bt1[i]); 13 | echoBuf[0x22+i] = encode(bt2[i]); 14 | } 15 | 16 | return; 17 | } 18 | 19 | void getEchoKey(const uint8_t *capBuf) 20 | { 21 | int i, offset = 0x1c+capBuf[0x1b]+0x69+24; /* 通过比较了大量抓包,通用的提取点就是这样的 */ 22 | u_char *base; 23 | echoKey = ntohl(*(u_int32_t *)(capBuf+offset)); 24 | base = (u_char *)(&echoKey); 25 | for (i=0; i<4; i++) 26 | base[i] = encode(base[i]); 27 | 28 | return; 29 | } 30 | 31 | static u_char encode(u_char base) /* 算法,将一个字节的8位颠倒并取反 */ 32 | { 33 | u_char result = 0; 34 | int i; 35 | for (i=0; i<8; i++) { 36 | result <<= 1; 37 | result |= base&0x01; 38 | base >>= 1; 39 | } 40 | 41 | return ~result; 42 | } 43 | 44 | u_char *encodeIP(u_int32_t ip) 45 | { 46 | int i; 47 | unsigned char *p = (unsigned char *)(&ip); 48 | static u_char pi[4]; 49 | for(i=0; i<4; ++i) { 50 | pi[i]=encode(p[i]); 51 | /* 52 | pi[i]=(pi[i]<<4)|(pi[i]>>4); 53 | pi[i]=((pi[i]<<2)&0xcc)|((pi[i]>>2)&0x33); 54 | pi[i]=((pi[i]<<1)&0xaa)|((pi[i]>>1)&0x55); 55 | pi[i]=~pi[i];*/ 56 | } 57 | return pi; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /src/mentohust_encryption/mento_md5.h: -------------------------------------------------------------------------------- 1 | /* MD5.H - header file for MD5.C */ 2 | 3 | /* 4 | Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 5 | rights reserved. 6 | License to copy and use this software is granted provided that it 7 | is identified as the "RSA Data Security, Inc. MD5 Message-Digest 8 | Algorithm" in all material mentioning or referencing this software 9 | or this function. 10 | License is also granted to make and use derivative works provided 11 | that such works are identified as "derived from the RSA Data 12 | Security, Inc. MD5 Message-Digest Algorithm" in all material 13 | mentioning or referencing the derived work. 14 | RSA Data Security, Inc. makes no representations concerning either 15 | the merchantability of this software or the suitability of this 16 | software for any particular purpose. It is provided "as is" 17 | without express or implied warranty of any kind. 18 | These notices must be retained in any copies of any part of this 19 | documentation and/or software.*/ 20 | 21 | #ifndef MD5_H 22 | #define MD5_H 23 | #include "types.h" 24 | 25 | /* MD5 context. */ 26 | typedef struct { 27 | UINT4 state[4]; /* state (ABCD) */ 28 | UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ 29 | UCHAR buffer[64]; /* input buffer */ 30 | } MD5_CTX; 31 | 32 | void MD5Init(MD5_CTX * context); 33 | void MD5Update(MD5_CTX *context, UCHAR *input, UINT4 inputLen); 34 | void MD5Final(UCHAR digest[16], MD5_CTX *context); 35 | 36 | UCHAR* ComputeHash(UCHAR *src, UINT4 len); 37 | 38 | #endif /* MD5_H */ 39 | -------------------------------------------------------------------------------- /src/functions.h: -------------------------------------------------------------------------------- 1 | #ifndef FUNCTIONS_ 2 | #define FUNCTIONS_ 3 | 4 | #include 5 | #include 6 | 7 | #ifndef __linux 8 | #include 9 | #else /* BSD System like macOS*/ 10 | #include 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "mentohust_encryption/md5.h" 19 | 20 | #include "init.h" 21 | #include "eap_frames_operations.h" 22 | 23 | 24 | 25 | static char* get_md5_digest(const char *str, size_t length); 26 | uint8_t 27 | *calculate_the_eap_md5_value_in_response_md5_challenge_frame( 28 | const uint8_t id, 29 | const uint8_t *eap_request_md5_chag_value, 30 | unsigned int eap_md5_value_size 31 | ); 32 | int code_convert(char *from_charset, char *to_charset, 33 | char *inbuf, size_t inlen, char *outbuf, size_t outlen); 34 | void print_server_info (const uint8_t *frame); 35 | void print_notification_msg(const uint8_t *frame); 36 | //extern void showRuijieMsg(const uint8_t *buf, unsigned bufLen); 37 | int midnight_relogin(); 38 | int relogin_when_receive_failure_frame(); 39 | void HandleSigalrm(int sig, siginfo_t *siginfo, void *context); 40 | void KeepOnline(); 41 | int LockRegister(int fd, int cmd, int type, off_t offset, int whence, off_t len); 42 | pid_t LockTest(int fd, int type, off_t offset, int whence, off_t len); 43 | int KillJMUSupplicant(int exit_flag, int fd, int type, off_t offset, int whence, off_t len); 44 | int initiative_exit_program_with_already_running_check(int exit_flag, int fd, pid_t pid); 45 | static int CleanMemory(); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /cmake/Modules/FindPCAP.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find libpcap include dirs and libraries 2 | # 3 | # Usage of this module as follows: 4 | # 5 | # find_package(PCAP) 6 | # 7 | # Variables used by this module, they can change the default behaviour and need 8 | # to be set before calling find_package: 9 | # 10 | # PCAP_ROOT_DIR Set this variable to the root installation of 11 | # libpcap if the module has problems finding the 12 | # proper installation path. 13 | # 14 | # Variables defined by this module: 15 | # 16 | # PCAP_FOUND System has libpcap, include and library dirs found 17 | # PCAP_INCLUDE_DIR The libpcap include directories. 18 | # PCAP_LIBRARY The libpcap library (possibly includes a thread 19 | # library e.g. required by pf_ring's libpcap) 20 | # HAVE_PF_RING If a found version of libpcap supports PF_RING 21 | 22 | find_path(PCAP_ROOT_DIR 23 | NAMES include/pcap.h 24 | ) 25 | 26 | find_path(PCAP_INCLUDE_DIR 27 | NAMES pcap.h 28 | HINTS ${PCAP_ROOT_DIR}/include 29 | ) 30 | 31 | find_library(PCAP_LIBRARY 32 | NAMES pcap 33 | HINTS ${PCAP_ROOT_DIR}/lib 34 | ) 35 | 36 | include(FindPackageHandleStandardArgs) 37 | find_package_handle_standard_args(PCAP DEFAULT_MSG 38 | PCAP_LIBRARY 39 | PCAP_INCLUDE_DIR 40 | ) 41 | 42 | include(CheckCSourceCompiles) 43 | set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY}) 44 | check_c_source_compiles("int main() { return 0; }" PCAP_LINKS_SOLO) 45 | set(CMAKE_REQUIRED_LIBRARIES) 46 | 47 | # check if linking against libpcap also needs to link against a thread library 48 | if (NOT PCAP_LINKS_SOLO) 49 | find_package(Threads) 50 | if (THREADS_FOUND) 51 | set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) 52 | check_c_source_compiles("int main() { return 0; }" PCAP_NEEDS_THREADS) 53 | set(CMAKE_REQUIRED_LIBRARIES) 54 | endif () 55 | if (THREADS_FOUND AND PCAP_NEEDS_THREADS) 56 | set(_tmp ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) 57 | list(REMOVE_DUPLICATES _tmp) 58 | set(PCAP_LIBRARY ${_tmp} 59 | CACHE STRING "Libraries needed to link against libpcap" FORCE) 60 | else () 61 | message(FATAL_ERROR "Couldn't determine how to link against libpcap") 62 | endif () 63 | endif () 64 | 65 | include(CheckFunctionExists) 66 | set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY}) 67 | check_function_exists(pcap_get_pfring_id HAVE_PF_RING) 68 | set(CMAKE_REQUIRED_LIBRARIES) 69 | 70 | mark_as_advanced( 71 | PCAP_ROOT_DIR 72 | PCAP_INCLUDE_DIR 73 | PCAP_LIBRARY 74 | ) -------------------------------------------------------------------------------- /cmake/Modules/FindIconv.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find iconv include dirs and libraries 2 | # 3 | # Usage of this module as follows: 4 | # 5 | # find_package(ICONV) 6 | # 7 | # Variables used by this module, they can change the default behaviour and need 8 | # to be set before calling find_package: 9 | # 10 | # ICONV_ROOT_DIR Set this variable to the root installation of 11 | # iconv if the module has problems finding the 12 | # proper installation path. 13 | # 14 | # Variables defined by this module: 15 | # 16 | # ICONV_FOUND System has iconv, include and library dirs found 17 | # ICONV_INCLUDE_DIR The iconv include directories. 18 | # ICONV_LIBRARY The iconv library (possibly includes a thread 19 | # library e.g. required by pf_ring's iconv) 20 | # HAVE_PF_RING If a found version of iconv supports PF_RING 21 | 22 | find_path(ICONV_ROOT_DIR 23 | NAMES include/iconv.h 24 | ) 25 | 26 | find_path(ICONV_INCLUDE_DIR 27 | NAMES iconv.h 28 | HINTS ${ICONV_ROOT_DIR}/include 29 | ) 30 | 31 | find_library(ICONV_LIBRARY 32 | NAMES ICONV 33 | HINTS ${ICONV_ROOT_DIR}/lib 34 | ) 35 | 36 | include(FindPackageHandleStandardArgs) 37 | find_package_handle_standard_args(ICONV DEFAULT_MSG 38 | ICONV_LIBRARY 39 | ICONV_INCLUDE_DIR 40 | ) 41 | 42 | include(CheckCSourceCompiles) 43 | set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARY}) 44 | check_c_source_compiles("int main() { return 0; }" ICONV_LINKS_SOLO) 45 | set(CMAKE_REQUIRED_LIBRARIES) 46 | 47 | # check if linking against iconv also needs to link against a thread library 48 | if (NOT ICONV_LINKS_SOLO) 49 | find_package(Threads) 50 | if (THREADS_FOUND) 51 | set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) 52 | check_c_source_compiles("int main() { return 0; }" ICONV_NEEDS_THREADS) 53 | set(CMAKE_REQUIRED_LIBRARIES) 54 | endif () 55 | if (THREADS_FOUND AND ICONV_NEEDS_THREADS) 56 | set(_tmp ${ICONV_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) 57 | list(REMOVE_DUPLICATES _tmp) 58 | set(ICONV_LIBRARY ${_tmp} 59 | CACHE STRING "Libraries needed to link against iconv" FORCE) 60 | else () 61 | message(FATAL_ERROR "Couldn't determine how to link against iconv") 62 | endif () 63 | endif () 64 | 65 | include(CheckFunctionExists) 66 | set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARY}) 67 | check_function_exists(iconv_close HAVE_PF_RING) 68 | set(CMAKE_REQUIRED_LIBRARIES) 69 | 70 | mark_as_advanced( 71 | ICONV_ROOT_DIR 72 | ICONV_INCLUDE_DIR 73 | ICONV_LIBRARY 74 | ) -------------------------------------------------------------------------------- /src/init.h: -------------------------------------------------------------------------------- 1 | #ifndef INIT_ 2 | #define INIT_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #ifndef __linux 12 | #include 13 | #include 14 | #include 15 | #include 16 | #else /* if BSD */ 17 | #include 18 | #include 19 | #include 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | #include 30 | 31 | #define DEFAULT_DHCPMODE 0 32 | #define MAX_PATH 255 // dhcp script max size 33 | #define SERVICE_SIZE 127 // service_name max size 34 | #define ACCOUNT_SIZE 65 // username and password max size 35 | //#define DEFAULT_NIC_NAME "bnep0" 36 | #define MAC_LENGTH 6 37 | #define NIC_MAXHOST 1025 38 | #define NIC_SIZE 16 // the name of network interface card max size 39 | 40 | #define DEBUG 1 41 | 42 | typedef struct nic_struct { 43 | char nic_name[NIC_SIZE]; // network interface card name 44 | uint8_t nic_MAC[ETHER_ADDR_LEN]; // network interface card MAC address 45 | struct in_addr ipaddr; // ip address 46 | struct in_addr netmask; // network mask 47 | struct in_addr gateway; 48 | struct in_addr dns; 49 | } NIC_STRUCT; 50 | 51 | const static uint8_t SERVICE_EDUCATION[] = {0xbd, 0xcc, 0xd3, 0xfd, 0xcd, 0xf8, 0xbd, 0xd3, 0xc8, 0xeb}; //教育网接入 52 | const static uint8_t SERVICE_CHINA_UNICOM[] = {0xc1, 0xaa, 0xcd, 0xa8, 0xbf, 0xed, 0xb4, 0xf8, 0xbd, 0xd3, 0xc8, 0xeb}; // 联通宽带接入 53 | const static uint8_t SERVICE_CHINA_MOBILE[] = {0xd2, 0xc6, 0xb6, 0xaf, 0xbf, 0xed, 0xb4, 0xf8, 0xbd, 0xd3, 0xc8, 0xeb}; // 移动宽带接入 54 | const static uint8_t SERVICE_CHINA_TELECOM[] = {0xb5, 0xe7, 0xd0, 0xc5, 0xbf, 0xed, 0xb4, 0xf8, 0xbd, 0xd3, 0xc8, 0xeb}; // 电信宽带接入 55 | 56 | const static unsigned int SERVICE_EDUCATION_LENGTH = 10; // bytes number 57 | const static unsigned int SERVICE_CHINA_UNICOM_LENGTH = 12; 58 | const static unsigned int SERVICE_CHINA_MOBILE_LENGTH = 12; 59 | const static unsigned int SERVICE_CHINA_TELECOM_LENGTH = 12; 60 | 61 | const static unsigned int DEFAULT_SERVICE_NAME_SIZE = 32; 62 | const static char *DEFAULT_DHCPSCRIPT = "dhclient"; 63 | const static unsigned int DNS_LENGTH = 15; 64 | 65 | void init_login_config(); 66 | void init_device(); 67 | static void init_gateway(); 68 | static void init_DNS(); 69 | static void init_netmask(); 70 | static void init_ipaddr(); 71 | static void init_service_name(); 72 | int init_NIC_name(NIC_STRUCT *nic_info); 73 | int init_NIC_address(NIC_STRUCT *nic_info); 74 | static void PrintInitConfig(); 75 | 76 | #endif 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/mentohust_encryption/ampheck.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Copyright (C) 2009 Gabriel A. Petursson 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef AMPHECK_H 20 | #define AMPHECK_H 21 | #include 22 | 23 | #define ROR(x, y) (((x) >> (y)) ^ ((x) << ((sizeof(x) * 8) - (y)))) 24 | #define ROL(x, y) ((x) << (y) ^ ((x) >> (32 - (y)))) 25 | 26 | #define UNPACK_32_BE(x, str) { \ 27 | *((str)) = (uint8_t) ((x) >> 24); \ 28 | *((str) + 1) = (uint8_t) ((x) >> 16); \ 29 | *((str) + 2) = (uint8_t) ((x) >> 8); \ 30 | *((str) + 3) = (uint8_t) (x); \ 31 | } 32 | 33 | #define UNPACK_64_BE(x, str) { \ 34 | *((str)) = (uint8_t) ((x) >> 56); \ 35 | *((str) + 1) = (uint8_t) ((x) >> 48); \ 36 | *((str) + 2) = (uint8_t) ((x) >> 40); \ 37 | *((str) + 3) = (uint8_t) ((x) >> 32); \ 38 | *((str) + 4) = (uint8_t) ((x) >> 24); \ 39 | *((str) + 5) = (uint8_t) ((x) >> 16); \ 40 | *((str) + 6) = (uint8_t) ((x) >> 8); \ 41 | *((str) + 7) = (uint8_t) (x); \ 42 | } 43 | 44 | #define PACK_32_BE(str, x) { \ 45 | *(x) = ((uint32_t) *((str) ) << 24) \ 46 | ^ ((uint32_t) *((str) + 1) << 16) \ 47 | ^ ((uint32_t) *((str) + 2) << 8) \ 48 | ^ ((uint32_t) *((str) + 3)); \ 49 | } 50 | 51 | #define PACK_64_BE(str, x) { \ 52 | *(x) = ((uint64_t) *((str) ) << 56) \ 53 | ^ ((uint64_t) *((str) + 1) << 48) \ 54 | ^ ((uint64_t) *((str) + 2) << 40) \ 55 | ^ ((uint64_t) *((str) + 3) << 32) \ 56 | ^ ((uint64_t) *((str) + 4) << 24) \ 57 | ^ ((uint64_t) *((str) + 5) << 16) \ 58 | ^ ((uint64_t) *((str) + 6) << 8) \ 59 | ^ ((uint64_t) *((str) + 7)); \ 60 | } 61 | 62 | #define UNPACK_32_LE(x, str) { \ 63 | *((str)) = (uint8_t) (x); \ 64 | *((str) + 1) = (uint8_t) ((x) >> 8); \ 65 | *((str) + 2) = (uint8_t) ((x) >> 16); \ 66 | *((str) + 3) = (uint8_t) ((x) >> 24); \ 67 | } 68 | 69 | #define UNPACK_64_LE(x, str) { \ 70 | *((str)) = (uint8_t) (x); \ 71 | *((str) + 1) = (uint8_t) ((x) >> 8); \ 72 | *((str) + 2) = (uint8_t) ((x) >> 16); \ 73 | *((str) + 3) = (uint8_t) ((x) >> 24); \ 74 | *((str) + 4) = (uint8_t) ((x) >> 32); \ 75 | *((str) + 5) = (uint8_t) ((x) >> 40); \ 76 | *((str) + 6) = (uint8_t) ((x) >> 48); \ 77 | *((str) + 7) = (uint8_t) ((x) >> 56); \ 78 | } 79 | 80 | #define PACK_32_LE(str, x) { \ 81 | *(x) = ((uint32_t) *((str) )) \ 82 | ^ ((uint32_t) *((str) + 1) << 8) \ 83 | ^ ((uint32_t) *((str) + 2) << 16) \ 84 | ^ ((uint32_t) *((str) + 3) << 24); \ 85 | } 86 | 87 | #define PACK_64_LE(str, x) { \ 88 | *(x) = ((uint64_t) *((str) )) \ 89 | ^ ((uint64_t) *((str) + 1) << 8) \ 90 | ^ ((uint64_t) *((str) + 2) << 16) \ 91 | ^ ((uint64_t) *((str) + 3) << 24) \ 92 | ^ ((uint64_t) *((str) + 4) << 32) \ 93 | ^ ((uint64_t) *((str) + 5) << 40) \ 94 | ^ ((uint64_t) *((str) + 6) << 48) \ 95 | ^ ((uint64_t) *((str) + 7) << 56); \ 96 | } 97 | #endif 98 | -------------------------------------------------------------------------------- /src/mentohust_encryption/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | L. Peter Deutsch 21 | ghost@aladdin.com 22 | 23 | */ 24 | /* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ 25 | /* 26 | Independent implementation of MD5 (RFC 1321). 27 | 28 | This code implements the MD5 Algorithm defined in RFC 1321, whose 29 | text is available at 30 | http://www.ietf.org/rfc/rfc1321.txt 31 | The code is derived from the text of the RFC, including the test suite 32 | (section A.5) but excluding the rest of Appendix A. It does not include 33 | any code or documentation that is identified in the RFC as being 34 | copyrighted. 35 | 36 | The original and principal author of md5.h is L. Peter Deutsch 37 | . Other authors are noted in the change history 38 | that follows (in reverse chronological order): 39 | 40 | 2002-04-13 lpd Removed support for non-ANSI compilers; removed 41 | references to Ghostscript; clarified derivation from RFC 1321; 42 | now handles byte order either statically or dynamically. 43 | 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 44 | 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); 45 | added conditionalization for C++ compilation from Martin 46 | Purschke . 47 | 1999-05-03 lpd Original version. 48 | */ 49 | 50 | #ifndef md5_INCLUDED 51 | # define md5_INCLUDED 52 | 53 | /* 54 | * This package supports both compile-time and run-time determination of CPU 55 | * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be 56 | * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is 57 | * defined as non-zero, the code will be compiled to run only on big-endian 58 | * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to 59 | * run on either big- or little-endian CPUs, but will run slightly less 60 | * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. 61 | */ 62 | 63 | typedef unsigned char md5_byte_t; /* 8-bit byte */ 64 | typedef unsigned int md5_word_t; /* 32-bit word */ 65 | 66 | /* Define the state of the MD5 Algorithm. */ 67 | typedef struct md5_state_s { 68 | md5_word_t count[2]; /* message length in bits, lsw first */ 69 | md5_word_t abcd[4]; /* digest buffer */ 70 | md5_byte_t buf[64]; /* accumulate block */ 71 | } md5_state_t; 72 | 73 | #ifdef __cplusplus 74 | extern "C" 75 | { 76 | #endif 77 | 78 | /* Initialize the algorithm. */ 79 | void md5_init(md5_state_t *pms); 80 | 81 | /* Append a string to the message. */ 82 | void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); 83 | 84 | /* Finish the message and return the digest. */ 85 | void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); 86 | 87 | #ifdef __cplusplus 88 | } /* end extern "C" */ 89 | #endif 90 | 91 | #endif /* md5_INCLUDED */ 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jmuSupplicant 2 | 3 | [![License](https://img.shields.io/crates/l/rustc-serialize.svg)](https://raw.githubusercontent.com/ShanQincheng/jmuSupplicant/master/LICENSE) 4 | 5 | 这是一个适用于集美大学的第三方锐捷认证客户端。关于实现此客户端的实现过程,可以参考[锐捷认证过程分析与第三方锐捷认证客户端的设计与实现](https://github.com/ShanQincheng/jmuSupplicant/blob/master/doc/%E9%94%90%E6%8D%B7%E8%AE%A4%E8%AF%81%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90%E4%B8%8E%E7%AC%AC%E4%B8%89%E6%96%B9%E9%94%90%E6%8D%B7%E8%AE%A4%E8%AF%81%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0.pdf) 6 | 7 | 除了实现基础的认证并保持在线功能以外,额外实现了夜晚断网后认证功能。 8 | 9 | 普通认证支持所有服务类型的选择,夜晚断网后认证服务类型仅支持“教育网接入”。 10 | 11 | 经测试,12:00 p.m.后网速有较大提升,爱奇艺 1080P 勉强能够,抖音,微博毫无压力。 12 | 13 | # 编译 14 | 15 | ## 普通编译 16 | 17 | 首先请确保系统已安装 ```libpcap``` 库以及 ```CMake``` 。 18 | 19 | ```bash 20 | git clone https://github.com/ShanQincheng/jmuSupplicant.git 21 | cd jmuSupplicant 22 | mkdir build 23 | cd build 24 | cmake ../ 25 | make 26 | ``` 27 | 28 | 之后可以在 ```build/bin``` 目录下找到 jmuSupplicant 的可执行文件。 29 | 30 | ## 交叉编译 31 | 32 | 交叉编译需要先编译 libpcap ,之后再编译 jmuSupplicant。下面以交叉编译到 ar71xx 路由器为例:(以下代码中的一些参数需要根据你的实际情况做相应的修改,仅供参考) 33 | 34 | ### 获取目标设备的交叉编译工具链 35 | 36 | 从 [https://downloads.openwrt.org/](https://downloads.openwrt.org/) 上面下载目标设备的交叉编译工具链。例如 ar71xx 芯片的工具链下载地址为:[https://downloads.openwrt.org/releases/18.06.0/targets/ar71xx/generic/openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64.tar.xz](https://downloads.openwrt.org/releases/18.06.0/targets/ar71xx/generic/openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64.tar.xz) 37 | 38 | (若下载缓慢,可以到[清华大学镜像源](https://mirrors.tuna.tsinghua.edu.cn/lede/)以及[中国科学技术大学镜像源](https://mirrors.ustc.edu.cn/lede/)下载相应工具链) 39 | 40 | ```bash 41 | wget https://downloads.openwrt.org/releases/18.06.0/targets/ar71xx/generic/openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64.tar.xz 42 | tar xvJf openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64.tar.xz 43 | ``` 44 | 45 | ### 配置环境变量 46 | 47 | 环境变量中的具体路径以及参数要根据你的实际情况做相应的修改,以下代码仅供参考: 48 | 49 | ```bash 50 | export PATH=$PATH:/home/xxx/openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl/bin 51 | export CC=mips-openwrt-linux-gcc 52 | export CPP=mips-openwrt-linux-cpp 53 | export GCC=mips-openwrt-linux-gcc 54 | export CXX=mips-openwrt-linux-g++ 55 | export RANLIB=mips-openwrt-linux-ranlib 56 | export LC_ALL=C 57 | export LDFLAGS="-static" 58 | export CFLAGS="-Os -s" 59 | export STAGING_DIR=/home/xxx/openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl 60 | ``` 61 | 62 | ### 交叉编译 libpcap 63 | 64 | ```bash 65 | wget http://www.tcpdump.org/release/libpcap-1.9.0.tar.gz 66 | tar zxvf libpcap-1.9.0.tar.gz 67 | cd libpcap-1.9.0 68 | ./configure --host=mips-linux --with-pcap=linux 69 | make 70 | ``` 71 | 72 | 如果交叉编译 libpcap 的过程中遇到错误,不用担心,这里我们只需要用到 ```libpcap.a``` ,编译后能得到该文件即可。之后将该文件以及 libpcap 的相关头文件复制到工具链的目录中: 73 | 74 | ```bash 75 | cp libpcap.a /home/xxx/openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl/lib 76 | cp pcap.h /home/xxx/openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl/include 77 | cp -r pcap /home/xxx/openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl/include 78 | ``` 79 | 80 | ### 交叉编译 jmuSupplicant 81 | 82 | ```bash 83 | git clone https://github.com/ShanQincheng/jmuSupplicant.git 84 | cd jmuSupplicant 85 | mkdir build 86 | cd build 87 | cmake ../ -DCMAKE_FIND_ROOT_PATH=/home/xxx/openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY -DCMAKE_C_COMPILER=/home/xxx/openwrt-sdk-18.06.0-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl/bin/mips-openwrt-linux-gcc 88 | make 89 | ``` 90 | 91 | 之后可以在 ```build/bin``` 目录下找到 jmuSupplicant 的可执行文件。 92 | 93 | # 使用说明 94 | 95 | 可以通过```--help```参数来获取程序运行帮助,下面举例两种使用情况: 96 | 97 | ## 正常使用 98 | 99 | - 使用以下指令进行锐捷认证: 100 | 101 | ```bash 102 | sudo ./jmu -u学号 -p密码 -s0(教育网接入)1(联通宽带接入)2(移动宽带接入)3(电信宽带接入) -b 103 | ``` 104 | 105 | - 程序输出锐捷认证信息,或显示 login success, 则认证成功。 106 | 107 | ## 断网后的使用 108 | 109 | - 首先自行找寻办公区域(夜晚能认证锐捷的地方,比如办公大楼)的 IP 地址,例如:123.123.123.123 110 | 111 | - 使用以下指令进行断网后的锐捷认证: 112 | 113 | ```bash 114 | sudo ./jmuSupplicant.out -u学号 -p密码 -s0 -b -n --ip 123.123.123.123 115 | ``` 116 | 117 | - 程序输出锐捷认证信息,或显示 login success, 则认证成功。 118 | 119 | # 已测试稳定运行的设备 120 | 121 | - 计算机: 122 | - Ubuntu 17.10 123 | - Archlinux 4.17.8-1-ARCH 124 | - 路由器: 125 | - MT7620 126 | - ar71xx 127 | - 其他: 128 | - 树莓派 2B 129 | 130 | # License 131 | 132 | Apache version 2.0 133 | -------------------------------------------------------------------------------- /src/construct_eap_frames.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSTRUCT_FRAMES_ 2 | #define CONSTRUCT_FRAMES_ 3 | 4 | #define DEBUG 1 5 | //If using macos we should use sys/malloc.h instead of malloc.h 6 | // 7 | // Evsio0n 2020/7/28/7:14:08 8 | // 9 | //We should add different include type for libpcap to port it on macOS 10 | 11 | #ifndef __linux 12 | #include 13 | #else /* BSD like System macOS*/ 14 | #include 15 | #endif 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "init.h" 22 | #include "functions.h" 23 | #include "mentohust_encryption/md5.h" 24 | #include "mentohust_encryption/mentohustV4.h" 25 | #include "mentohust_encryption/mento_myfun.h" 26 | 27 | // EAPOL START FRAME 28 | const static unsigned int ETHERNET_TYPE_LENGTH = 2; 29 | const static unsigned int ETHERNET_HEADER_LENGTH = 14; 30 | const static unsigned int EAPOL_VERSION_LENGTH = 1; 31 | const static unsigned int EAPOL_TYPE_LENGTH = 1; 32 | const static unsigned int EAPOL_FRAME_LENGTH = 2; 33 | const static unsigned int ETHERNET_PADDING_LENGTH = 42; 34 | const static unsigned int ETHERNET_TRAILER_LENGTH = 507; 35 | 36 | const static unsigned int EAPOL_START_IP_ADDR = 0X17; 37 | const static unsigned int EAPOL_START_NETMASK_ADDR = 0X1B; 38 | const static unsigned int EAPOL_START_GATEWAY_ADDR = 0X1F; 39 | const static unsigned int EAPOL_START_SERVICE_NAME_ADDR = 0x193; 40 | 41 | // EAP RESPONSE IDENTITY FRAME 42 | const static unsigned int EAP_HEADER_LENGTH = 4; 43 | const static unsigned int EAP_TYPE_LENGTH = 1; 44 | const static unsigned int EAP_IDENTITY_PADDING_LENGTH = 25; 45 | const static unsigned int EAP_IDENTITY_TRAILER_LENGTH = 524; 46 | const static unsigned int EAP_IDENTITY_RESPONSE_SERVICE_NAME_ADDR = 0x1a4; 47 | const static unsigned int EAP_IDENTITY_RESPONSE_IP_ADDR = 0x28; 48 | const static unsigned int EAP_IDENTITY_RESPONSE_NETMASK_ADDR = 0X2c; 49 | const static unsigned int EAP_IDENTITY_RESPONSE_GATEWAY_ADDR = 0X30; 50 | 51 | const static unsigned int EAP_ID_ADDRESS_IN_EAP_IDENTITY_REQUEST_FRAME = 0X13; 52 | 53 | // EAP RESPONSE MD5 CHALLENGE FRAME 54 | const static unsigned int EAP_MD5_VALUE_SIZE_LENGTH = 1; 55 | const static unsigned int EAP_MD5_VALUE_LENGTH = 16; 56 | const static unsigned int EAP_MD5_CHALLENGE_PADDING_LENGTH = 8; 57 | const static unsigned int EAP_MD5_CHALLENGE_TRAILER_LENGTH = 545; 58 | const static unsigned int SERVICE_NAME_LENGTH = 32; 59 | 60 | const static unsigned int EAP_MD5_RESPONSE_IP_ADDR = 0X39; 61 | const static unsigned int EAP_MD5_RESPONSE_NETMASK_ADDR = 0X3D; 62 | const static unsigned int EAP_MD5_RESPONSE_GATEWAY_ADDR = 0X41; 63 | const static unsigned int EAP_MD5_RESPONSE_COMPUTE_PASSWORD_ADDR = 0XB8; 64 | const static unsigned int EAP_MD5_RESPONSE_COMPUTE_V4_ADDR = 0X121; 65 | const static unsigned int EAP_MD5_RESPONSE_SERVICE_NAME_ADDR = 0X1B5; 66 | 67 | const static unsigned int EAP_ID_ADDRESS_IN_EAP_MD5_REQUEST_FRAME = 0X13; 68 | const static unsigned int EAP_MD5_VALUE_SIZE_ADDRESS_IN_EAP_MD5_REQUEST_FRAME = 0X17; 69 | 70 | // EAPOL HEARTBEAT FRAME 71 | const static unsigned int EAPOL_HEARTBEAT_DATA_LENGTH = 27; 72 | 73 | // use in midnight mode 74 | const static unsigned SWITCH_SERVICE_TAIL_DATA_START_LENGTH = 56; 75 | const static unsigned SWITCH_SERVICE_TAIL_DATA_MD5_CHALLENGE_LENGTH = 66; 76 | const static unsigned TAIL_DATA_ADDRESS_IN_START = 0x208; 77 | //const static unsigned TAIL_DATA_ADDRESS_IN_IDENTITY = 0x210; 78 | const static unsigned TAIL_DATA_ADDRESS_IN_MD5_CHALLENGE = 0x221; 79 | 80 | static void construct_ethernet_frame_header(uint8_t *packet, const uint8_t *src_MAC, const uint8_t *dst_MAC, const uint16_t ether_type); 81 | void construct_eapol_start_frame(const uint8_t *frame); 82 | void construct_eap_response_identity_frame(const uint8_t *frame); 83 | void construct_eap_response_md5_challenge_frame(const uint8_t *frame); 84 | void construct_eapol_heartbeat_frame(const uint8_t *frame); 85 | 86 | // 断网后重新认证, 分别填充到 START FRAME 和 MD5-CHALLENGE FRAME 的尾部数据 87 | const static uint8_t SWITCH_SERVICE_TAIL_DATA_START[] = {0x13, 0x11, 0x64, 0x04, 0x00, 0x01, 0x1a, 0x09, 0x00, 0x00, 0x13, 0x11, 0x6b, 0x03, 0x00, 0x1a, 0x09, 0x00, 0x00, 0x13, 0x11, 0x70, 0x03, 0x40, 0x1a, 0x09, 0x00, 0x00, 0x13, 0x11, 0x6f, 0x03, 0x00, 0x1a, 0x09, 0x00, 0x00, 0x13, 0x11, 0x79, 0x03, 0x02, 0x1a, 0x0f, 0x00, 0x00, 0x13, 0x11, 0x76, 0x09, 0x38, 0x2e, 0x38, 0x2e, 0x34, 0x2e, 0x34}; 88 | const static uint8_t SWITCH_SERVICE_TAIL_DATA_MD5_CHALLENGE[] = {0x13, 0x11, 0x62, 0x03, 0x00, 0x1a, 0x0a, 0x00, 0x00, 0x13, 0x11, 0x64, 0x04, 0x00, 0x01, 0x1a, 0x09, 0x00, 0x00, 0x13, 0x11, 0x6b, 0x03, 0x00, 0x1a, 0x09, 0x00, 0x00, 0x13, 0x11, 0x70, 0x03, 0x40, 0x1a, 0x09, 0x00, 0x00, 0x13, 0x11, 0x6f, 0x03, 0x00, 0x1a, 0x09, 0x00, 0x00, 0x13, 0x11, 0x79, 0x03, 0x02, 0x1a, 0x0f, 0x00, 0x00, 0x13, 0x11, 0x76, 0x09, 0x38, 0x2e, 0x38, 0x2e, 0x34, 0x2e, 0x34}; 89 | 90 | 91 | #endif 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/mentohust_encryption/byte_order.c.orig: -------------------------------------------------------------------------------- 1 | /* byte_order.c - byte order related platform dependent routines, 2 | * 3 | * Copyright: 2008-2012 Aleksey Kravchenko 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! 15 | */ 16 | #include "byte_order.h" 17 | 18 | #if !(__GNUC__ >= 4 || (__GNUC__ ==3 && __GNUC_MINOR__ >= 4)) /* if !GCC or GCC < 4.3 */ 19 | 20 | # if _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) /* if MSVC++ >= 2002 on x86/x64 */ 21 | # include 22 | # pragma intrinsic(_BitScanForward) 23 | 24 | /** 25 | * Returns index of the trailing bit of x. 26 | * 27 | * @param x the number to process 28 | * @return zero-based index of the trailing bit 29 | */ 30 | unsigned rhash_ctz(unsigned x) 31 | { 32 | unsigned long index; 33 | unsigned char isNonzero = _BitScanForward(&index, x); /* MSVC intrinsic */ 34 | return (isNonzero ? (unsigned)index : 0); 35 | } 36 | # else /* _MSC_VER >= 1300... */ 37 | 38 | /** 39 | * Returns index of the trailing bit of a 32-bit number. 40 | * This is a plain C equivalent for GCC __builtin_ctz() bit scan. 41 | * 42 | * @param x the number to process 43 | * @return zero-based index of the trailing bit 44 | */ 45 | unsigned rhash_ctz(unsigned x) 46 | { 47 | /* array for conversion to bit position */ 48 | static unsigned char bit_pos[32] = { 49 | 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 50 | 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 51 | }; 52 | 53 | /* The De Bruijn bit-scan was devised in 1997, according to Donald Knuth 54 | * by Martin Lauter. The constant 0x077CB531UL is a De Bruijn sequence, 55 | * which produces a unique pattern of bits into the high 5 bits for each 56 | * possible bit position that it is multiplied against. 57 | * See http://graphics.stanford.edu/~seander/bithacks.html 58 | * and http://chessprogramming.wikispaces.com/BitScan */ 59 | return (unsigned)bit_pos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27]; 60 | } 61 | # endif /* _MSC_VER >= 1300... */ 62 | #endif /* !(GCC >= 4.3) */ 63 | 64 | /** 65 | * Copy a memory block with simultaneous exchanging byte order. 66 | * The byte order is changed from little-endian 32-bit integers 67 | * to big-endian (or vice-versa). 68 | * 69 | * @param to the pointer where to copy memory block 70 | * @param index the index to start writing from 71 | * @param from the source block to copy 72 | * @param length length of the memory block 73 | */ 74 | void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length) 75 | { 76 | /* if all pointers and length are 32-bits aligned */ 77 | if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | index | length ) & 3) ) { 78 | /* copy memory as 32-bit words */ 79 | const uint32_t* src = (const uint32_t*)from; 80 | const uint32_t* end = (const uint32_t*)((const char*)src + length); 81 | uint32_t* dst = (uint32_t*)((char*)to + index); 82 | while (src < end) *(dst++) = bswap_32( *(src++) ); 83 | } else { 84 | const char* src = (const char*)from; 85 | for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 3] = *(src++); 86 | } 87 | } 88 | 89 | /** 90 | * Copy a memory block with changed byte order. 91 | * The byte order is changed from little-endian 64-bit integers 92 | * to big-endian (or vice-versa). 93 | * 94 | * @param to the pointer where to copy memory block 95 | * @param index the index to start writing from 96 | * @param from the source block to copy 97 | * @param length length of the memory block 98 | */ 99 | void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length) 100 | { 101 | /* if all pointers and length are 64-bits aligned */ 102 | if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | index | length ) & 7) ) { 103 | /* copy aligned memory block as 64-bit integers */ 104 | const uint64_t* src = (const uint64_t*)from; 105 | const uint64_t* end = (const uint64_t*)((const char*)src + length); 106 | uint64_t* dst = (uint64_t*)((char*)to + index); 107 | while (src < end) *(dst++) = bswap_64( *(src++) ); 108 | } else { 109 | const char* src = (const char*)from; 110 | for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 7] = *(src++); 111 | } 112 | } 113 | 114 | /** 115 | * Copy data from a sequence of 64-bit words to a binary string of given length, 116 | * while changing byte order. 117 | * 118 | * @param to the binary string to receive data 119 | * @param from the source sequence of 64-bit words 120 | * @param length the size in bytes of the data being copied 121 | */ 122 | void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length) 123 | { 124 | /* if all pointers and length are 64-bits aligned */ 125 | if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | length ) & 7) ) { 126 | /* copy aligned memory block as 64-bit integers */ 127 | const uint64_t* src = (const uint64_t*)from; 128 | const uint64_t* end = (const uint64_t*)((const char*)src + length); 129 | uint64_t* dst = (uint64_t*)to; 130 | while (src < end) *(dst++) = bswap_64( *(src++) ); 131 | } else { 132 | size_t index; 133 | char* dst = (char*)to; 134 | for (index = 0; index < length; index++) *(dst++) = ((char*)from)[index ^ 7]; 135 | } 136 | } 137 | 138 | /** 139 | * Exchange byte order in the given array of 32-bit integers. 140 | * 141 | * @param arr the array to process 142 | * @param length array length 143 | */ 144 | void rhash_u32_mem_swap(unsigned *arr, int length) 145 | { 146 | unsigned* end = arr + length; 147 | for (; arr < end; arr++) { 148 | *arr = bswap_32(*arr); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/mentohust_encryption/rjsha1.c: -------------------------------------------------------------------------------- 1 | /* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1) 2 | * based on RFC 3174. 3 | * 4 | * Copyright: 2008-2012 Aleksey Kravchenko 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a 7 | * copy of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 | * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! 16 | */ 17 | 18 | #include 19 | #include "byte_order.h" 20 | #include "rjsha1.h" 21 | 22 | /** 23 | * Initialize context before calculaing hash. 24 | * 25 | * @param ctx context to initialize 26 | */ 27 | void rhash_sha1_init(sha1_ctx *ctx) 28 | { 29 | ctx->length = 0; 30 | 31 | /* initialize algorithm state */ 32 | ctx->hash[0] = 0x32075416; 33 | ctx->hash[1] = 0xf8dae9bc; 34 | ctx->hash[2] = 0x73541260; 35 | ctx->hash[3] = 0x8acb9dfe; 36 | ctx->hash[4] = 0xfd0c2e1b; 37 | } 38 | 39 | /** 40 | * The core transformation. Process a 512-bit block. 41 | * The function has been taken from RFC 3174 with little changes. 42 | * 43 | * @param hash algorithm state 44 | * @param block the message block to process 45 | */ 46 | static void rhash_sha1_process_block(unsigned* hash, const unsigned* block) 47 | { 48 | int t; /* Loop counter */ 49 | uint32_t temp; /* Temporary word value */ 50 | uint32_t W[80]; /* Word sequence */ 51 | uint32_t A, B, C, D, E; /* Word buffers */ 52 | 53 | /* initialize the first 16 words in the array W */ 54 | for (t = 0; t < 16; t++) { 55 | /* note: it is much faster to apply be2me here, then using be32_copy */ 56 | W[t] = be2me_32(block[t]); 57 | } 58 | 59 | /* initialize the rest */ 60 | for (t = 16; t < 80; t++) { 61 | W[t] = ROTL32(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); 62 | } 63 | 64 | A = hash[0]; 65 | B = hash[1]; 66 | C = hash[2]; 67 | D = hash[3]; 68 | E = hash[4]; 69 | 70 | for (t = 0; t < 20; t++) { 71 | /* the following is faster than ((B & C) | ((~B) & D)) */ 72 | temp = ROTL32(A, 5) + (((C ^ D) & B) ^ D) 73 | + E + W[t] - 0x5d6aa4d4; 74 | E = D; 75 | D = C; 76 | C = ROTL32(B, 30); 77 | B = A; 78 | A = temp; 79 | } 80 | 81 | for (t = 20; t < 40; t++) { 82 | temp = ROTL32(A, 5) + (B ^ C ^ D) + E + W[t] + 0x16ae9deb + (uint8_t)(le2me_32(block[0])); //Leave to debug 83 | E = D; 84 | D = C; 85 | C = ROTL32(B, 30); 86 | B = A; 87 | A = temp; 88 | } 89 | 90 | for (t = 40; t < 61; t++) { 91 | temp = ROTL32(A, 5) + ((B & C) | (B & D) | (C & D)) 92 | + E + W[t] - 0x34032e48; 93 | E = D; 94 | D = C; 95 | C = ROTL32(B, 30); 96 | B = A; 97 | A = temp; 98 | } 99 | 100 | for (t = 61; t < 80; t++) { 101 | temp = ROTL32(A, 5) + (B ^ C ^ D) + E + W[t] - 0x5cd39e93; 102 | E = D; 103 | D = C; 104 | C = ROTL32(B, 30); 105 | B = A; 106 | A = temp; 107 | } 108 | 109 | hash[0] += A + 1; 110 | hash[1] += B; 111 | hash[2] += C; 112 | hash[3] += D; 113 | hash[4] += E; 114 | } 115 | 116 | /** 117 | * Calculate message hash. 118 | * Can be called repeatedly with chunks of the message to be hashed. 119 | * 120 | * @param ctx the algorithm context containing current hashing state 121 | * @param msg message chunk 122 | * @param size length of the message chunk 123 | */ 124 | void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size) 125 | { 126 | unsigned index = (unsigned)ctx->length & 63; 127 | ctx->length += size; 128 | 129 | /* fill partial block */ 130 | if (index) { 131 | unsigned left = sha1_block_size - index; 132 | memcpy(ctx->message + index, msg, (size < left ? size : left)); 133 | if (size < left) return; 134 | 135 | /* process partial block */ 136 | rhash_sha1_process_block(ctx->hash, (unsigned*)ctx->message); 137 | msg += left; 138 | size -= left; 139 | } 140 | while (size >= sha1_block_size) { 141 | unsigned* aligned_message_block; 142 | if (IS_ALIGNED_32(msg)) { 143 | /* the most common case is processing of an already aligned message 144 | without copying it */ 145 | aligned_message_block = (unsigned*)msg; 146 | } else { 147 | memcpy(ctx->message, msg, sha1_block_size); 148 | aligned_message_block = (unsigned*)ctx->message; 149 | } 150 | 151 | rhash_sha1_process_block(ctx->hash, aligned_message_block); 152 | msg += sha1_block_size; 153 | size -= sha1_block_size; 154 | } 155 | if (size) { 156 | /* save leftovers */ 157 | memcpy(ctx->message, msg, size); 158 | } 159 | } 160 | 161 | /** 162 | * Store calculated hash into the given array. 163 | * 164 | * @param ctx the algorithm context containing current hashing state 165 | * @param result calculated hash in binary form 166 | */ 167 | void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result) 168 | { 169 | unsigned index = (unsigned)ctx->length & 63; 170 | unsigned* msg32 = (unsigned*)ctx->message; 171 | 172 | /* pad message and run for last block */ 173 | ctx->message[index++] = 0x80; 174 | while ((index & 3) != 0) { 175 | ctx->message[index++] = 0; 176 | } 177 | index >>= 2; 178 | 179 | /* if no room left in the message to store 64-bit message length */ 180 | if (index > 14) { 181 | /* then fill the rest with zeros and process it */ 182 | while (index < 16) { 183 | msg32[index++] = 0; 184 | } 185 | rhash_sha1_process_block(ctx->hash, msg32); 186 | index = 0; 187 | } 188 | while (index < 14) { 189 | msg32[index++] = 0; 190 | } 191 | msg32[14] = be2me_32( (unsigned)(ctx->length >> 29) ); 192 | msg32[15] = be2me_32( (unsigned)(ctx->length << 3) ); 193 | rhash_sha1_process_block(ctx->hash, msg32); 194 | 195 | if (result) be32_copy(result, 0, &ctx->hash, sha1_hash_size); 196 | } 197 | -------------------------------------------------------------------------------- /src/mentohust_encryption/byte_order.c: -------------------------------------------------------------------------------- 1 | /* byte_order.c - byte order related platform dependent routines, 2 | * 3 | * Copyright: 2008-2012 Aleksey Kravchenko 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! 15 | */ 16 | #include "byte_order.h" 17 | 18 | #if !(__GNUC__ >= 4 || (__GNUC__ ==3 && __GNUC_MINOR__ >= 4)) /* if !GCC or GCC < 4.3 */ 19 | 20 | # if _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) /* if MSVC++ >= 2002 on x86/x64 */ 21 | # include 22 | # pragma intrinsic(_BitScanForward) 23 | 24 | /** 25 | * Returns index of the trailing bit of x. 26 | * 27 | * @param x the number to process 28 | * @return zero-based index of the trailing bit 29 | */ 30 | unsigned rhash_ctz(unsigned x) 31 | { 32 | unsigned long index; 33 | unsigned char isNonzero = _BitScanForward(&index, x); /* MSVC intrinsic */ 34 | return (isNonzero ? (unsigned)index : 0); 35 | } 36 | # else /* _MSC_VER >= 1300... */ 37 | 38 | /** 39 | * Returns index of the trailing bit of a 32-bit number. 40 | * This is a plain C equivalent for GCC __builtin_ctz() bit scan. 41 | * 42 | * @param x the number to process 43 | * @return zero-based index of the trailing bit 44 | */ 45 | unsigned rhash_ctz(unsigned x) 46 | { 47 | /* array for conversion to bit position */ 48 | static unsigned char bit_pos[32] = { 49 | 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 50 | 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 51 | }; 52 | 53 | /* The De Bruijn bit-scan was devised in 1997, according to Donald Knuth 54 | * by Martin Lauter. The constant 0x077CB531UL is a De Bruijn sequence, 55 | * which produces a unique pattern of bits into the high 5 bits for each 56 | * possible bit position that it is multiplied against. 57 | * See http://graphics.stanford.edu/~seander/bithacks.html 58 | * and http://chessprogramming.wikispaces.com/BitScan */ 59 | return (unsigned)bit_pos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27]; 60 | } 61 | # endif /* _MSC_VER >= 1300... */ 62 | #endif /* !(GCC >= 4.3) */ 63 | 64 | /** 65 | * Copy a memory block with simultaneous exchanging byte order. 66 | * The byte order is changed from little-endian 32-bit integers 67 | * to big-endian (or vice-versa). 68 | * 69 | * @param to the pointer where to copy memory block 70 | * @param index the index to start writing from 71 | * @param from the source block to copy 72 | * @param length length of the memory block 73 | */ 74 | void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length) 75 | { 76 | /* if all pointers and length are 32-bits aligned */ 77 | if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | index | length ) & 3) ) { 78 | /* copy memory as 32-bit words */ 79 | const uint32_t* src = (const uint32_t*)from; 80 | const uint32_t* end = (const uint32_t*)((const char*)src + length); 81 | uint32_t* dst = (uint32_t*)((char*)to + index); 82 | while (src < end) *(dst++) = bswap_32( *(src++) ); 83 | } else { 84 | const char* src = (const char*)from; 85 | for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 3] = *(src++); 86 | } 87 | } 88 | 89 | /** 90 | * Copy a memory block with changed byte order. 91 | * The byte order is changed from little-endian 64-bit integers 92 | * to big-endian (or vice-versa). 93 | * 94 | * @param to the pointer where to copy memory block 95 | * @param index the index to start writing from 96 | * @param from the source block to copy 97 | * @param length length of the memory block 98 | */ 99 | void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length) 100 | { 101 | /* if all pointers and length are 64-bits aligned */ 102 | if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | index | length ) & 7) ) { 103 | /* copy aligned memory block as 64-bit integers */ 104 | const uint64_t* src = (const uint64_t*)from; 105 | const uint64_t* end = (const uint64_t*)((const char*)src + length); 106 | uint64_t* dst = (uint64_t*)((char*)to + index); 107 | while (src < end) *(dst++) = bswap_64( *(src++) ); 108 | } else { 109 | const char* src = (const char*)from; 110 | for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 7] = *(src++); 111 | } 112 | } 113 | 114 | /** 115 | * Copy data from a sequence of 64-bit words to a binary string of given length, 116 | * while changing byte order. 117 | * 118 | * @param to the binary string to receive data 119 | * @param from the source sequence of 64-bit words 120 | * @param length the size in bytes of the data being copied 121 | */ 122 | void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length) 123 | { 124 | /* if all pointers and length are 64-bits aligned */ 125 | if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | length ) & 7) ) { 126 | /* copy aligned memory block as 64-bit integers */ 127 | const uint64_t* src = (const uint64_t*)from; 128 | const uint64_t* end = (const uint64_t*)((const char*)src + length); 129 | uint64_t* dst = (uint64_t*)to; 130 | while (src < end) *(dst++) = bswap_64( *(src++) ); 131 | } else { 132 | size_t index; 133 | char* dst = (char*)to; 134 | for (index = 0; index < length; index++) *(dst++) = ((char*)from)[index ^ 7]; 135 | } 136 | } 137 | 138 | /** 139 | * Exchange byte order in the given array of 32-bit integers. 140 | * 141 | * @param arr the array to process 142 | * @param length array length 143 | */ 144 | void rhash_u32_mem_swap(unsigned *arr, int length) 145 | { 146 | unsigned* end = arr + length; 147 | for (; arr < end; arr++) { 148 | *arr = bswap_32(*arr); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/mentohust_encryption/byte_order.h: -------------------------------------------------------------------------------- 1 | /* byte_order.h */ 2 | #ifndef BYTE_ORDER_H 3 | #define BYTE_ORDER_H 4 | #include "ustd.h" 5 | #include 6 | 7 | #ifdef IN_RHASH 8 | #include "config.h" 9 | #endif 10 | 11 | #ifdef __GLIBC__ 12 | # include 13 | #endif 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /* if x86 compatible cpu */ 20 | #if defined(i386) || defined(__i386__) || defined(__i486__) || \ 21 | defined(__i586__) || defined(__i686__) || defined(__pentium__) || \ 22 | defined(__pentiumpro__) || defined(__pentium4__) || \ 23 | defined(__nocona__) || defined(prescott) || defined(__core2__) || \ 24 | defined(__k6__) || defined(__k8__) || defined(__athlon__) || \ 25 | defined(__amd64) || defined(__amd64__) || \ 26 | defined(__x86_64) || defined(__x86_64__) || defined(_M_IX86) || \ 27 | defined(_M_AMD64) || defined(_M_IA64) || defined(_M_X64) 28 | /* detect if x86-64 instruction set is supported */ 29 | # if defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \ 30 | defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) 31 | # define CPU_X64 32 | # else 33 | # define CPU_IA32 34 | # endif 35 | #endif 36 | 37 | 38 | /* detect CPU endianness */ 39 | #if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ 40 | __BYTE_ORDER == __LITTLE_ENDIAN) || \ 41 | defined(CPU_IA32) || defined(CPU_X64) || \ 42 | defined(__ia64) || defined(__ia64__) || defined(__alpha__) || defined(_M_ALPHA) || \ 43 | defined(vax) || defined(MIPSEL) || defined(_ARM_) || defined(__arm__) 44 | # define CPU_LITTLE_ENDIAN 45 | # define IS_BIG_ENDIAN 0 46 | # define IS_LITTLE_ENDIAN 1 47 | #elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ 48 | __BYTE_ORDER == __BIG_ENDIAN) || \ 49 | defined(__sparc) || defined(__sparc__) || defined(sparc) || \ 50 | defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_POWER) || \ 51 | defined(__POWERPC__) || defined(POWERPC) || defined(__powerpc) || \ 52 | defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || \ 53 | defined(__hpux) || defined(_MIPSEB) || defined(mc68000) || \ 54 | defined(__s390__) || defined(__s390x__) || defined(sel) 55 | # define CPU_BIG_ENDIAN 56 | # define IS_BIG_ENDIAN 1 57 | # define IS_LITTLE_ENDIAN 0 58 | #else 59 | # error "Can't detect CPU architechture" 60 | #endif 61 | 62 | #define IS_ALIGNED_32(p) (0 == (3 & ((const char*)(p) - (const char*)0))) 63 | #define IS_ALIGNED_64(p) (0 == (7 & ((const char*)(p) - (const char*)0))) 64 | 65 | #if defined(_MSC_VER) 66 | #define ALIGN_ATTR(n) __declspec(align(n)) 67 | #elif defined(__GNUC__) 68 | #define ALIGN_ATTR(n) __attribute__((aligned (n))) 69 | #else 70 | #define ALIGN_ATTR(n) /* nothing */ 71 | #endif 72 | 73 | 74 | #if defined(_MSC_VER) || defined(__BORLANDC__) 75 | #define I64(x) x##ui64 76 | #else 77 | #define I64(x) x##LL 78 | #endif 79 | 80 | /* convert a hash flag to index */ 81 | #if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) /* GCC < 3.4 */ 82 | # define rhash_ctz(x) __builtin_ctz(x) 83 | #else 84 | unsigned rhash_ctz(unsigned); /* define as function */ 85 | #endif 86 | 87 | void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length); 88 | void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length); 89 | void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length); 90 | void rhash_u32_mem_swap(unsigned *p, int length_in_u32); 91 | 92 | /* define bswap_32 */ 93 | #if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__) 94 | /* for intel x86 CPU */ 95 | static inline uint32_t bswap_32(uint32_t x) 96 | { 97 | __asm("bswap\t%0" : "=r" (x) : "0" (x)); 98 | return x; 99 | } 100 | #elif defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3) 101 | /* for GCC >= 4.3 */ 102 | # define bswap_32(x) __builtin_bswap32(x) 103 | #elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */ 104 | # define bswap_32(x) _byteswap_ulong((unsigned long)x) 105 | #elif !defined(__STRICT_ANSI__) 106 | /* general bswap_32 definition */ 107 | static inline uint32_t bswap_32(uint32_t x) 108 | { 109 | x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0x00FF00FF); 110 | return (x >> 16) | (x << 16); 111 | } 112 | #else 113 | #define bswap_32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ 114 | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) 115 | #endif /* bswap_32 */ 116 | 117 | #if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3) 118 | # define bswap_64(x) __builtin_bswap64(x) 119 | #elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */ 120 | # define bswap_64(x) _byteswap_uint64((__int64)x) 121 | #elif !defined(__STRICT_ANSI__) 122 | static inline uint64_t bswap_64(uint64_t x) 123 | { 124 | union { 125 | uint64_t ll; 126 | uint32_t l[2]; 127 | } w, r; 128 | w.ll = x; 129 | r.l[0] = bswap_32(w.l[1]); 130 | r.l[1] = bswap_32(w.l[0]); 131 | return r.ll; 132 | } 133 | #else 134 | #error "bswap_64 unsupported" 135 | #endif 136 | 137 | #ifdef CPU_BIG_ENDIAN 138 | # define be2me_32(x) (x) 139 | # define be2me_64(x) (x) 140 | # define le2me_32(x) bswap_32(x) 141 | # define le2me_64(x) bswap_64(x) 142 | 143 | # define be32_copy(to, index, from, length) memcpy((to) + (index), (from), (length)) 144 | # define le32_copy(to, index, from, length) rhash_swap_copy_str_to_u32((to), (index), (from), (length)) 145 | # define be64_copy(to, index, from, length) memcpy((to) + (index), (from), (length)) 146 | # define le64_copy(to, index, from, length) rhash_swap_copy_str_to_u64((to), (index), (from), (length)) 147 | # define me64_to_be_str(to, from, length) memcpy((to), (from), (length)) 148 | # define me64_to_le_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length)) 149 | 150 | #else /* CPU_BIG_ENDIAN */ 151 | # define be2me_32(x) bswap_32(x) 152 | # define be2me_64(x) bswap_64(x) 153 | # define le2me_32(x) (x) 154 | # define le2me_64(x) (x) 155 | 156 | # define be32_copy(to, index, from, length) rhash_swap_copy_str_to_u32((to), (index), (from), (length)) 157 | # define le32_copy(to, index, from, length) memcpy((to) + (index), (from), (length)) 158 | # define be64_copy(to, index, from, length) rhash_swap_copy_str_to_u64((to), (index), (from), (length)) 159 | # define le64_copy(to, index, from, length) memcpy((to) + (index), (from), (length)) 160 | # define me64_to_be_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length)) 161 | # define me64_to_le_str(to, from, length) memcpy((to), (from), (length)) 162 | #endif /* CPU_BIG_ENDIAN */ 163 | 164 | /* ROTL/ROTR macros rotate a 32/64-bit word left/right by n bits */ 165 | #define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n)))) 166 | #define ROTR32(dword, n) ((dword) >> (n) ^ ((dword) << (32 - (n)))) 167 | #define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n)))) 168 | #define ROTR64(qword, n) ((qword) >> (n) ^ ((qword) << (64 - (n)))) 169 | 170 | #ifdef __cplusplus 171 | } /* extern "C" */ 172 | #endif /* __cplusplus */ 173 | 174 | #endif /* BYTE_ORDER_H */ 175 | -------------------------------------------------------------------------------- /src/mentohust_encryption/rjtiger.c: -------------------------------------------------------------------------------- 1 | /* tiger.c - an implementation of Tiger Hash Function 2 | * based on the article by 3 | * Ross Anderson and Eli Biham "Tiger: A Fast New Hash Function". 4 | * 5 | * Copyright: 2007-2012 Aleksey Kravchenko 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a 8 | * copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | * and/or sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so. 13 | * 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 | * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! 17 | */ 18 | 19 | #include 20 | #include "byte_order.h" 21 | #include "rjtiger.h" 22 | 23 | /** 24 | * Initialize algorithm context before calculaing hash. 25 | * 26 | * @param ctx context to initialize 27 | */ 28 | void rhash_tiger_init(tiger_ctx *ctx) 29 | { 30 | ctx->length = 0; 31 | ctx->tiger2 = 0; 32 | 33 | /* initialize algorithm state */ 34 | ctx->hash[0] = I64(0x158e427ac96b03df); 35 | ctx->hash[1] = I64(0xf025c13b8e9da784); 36 | ctx->hash[2] = I64(0xb690ab45c3e21b74); 37 | } 38 | 39 | /* lookup tables */ 40 | extern uint64_t rhash_tiger_sboxes[4][256]; 41 | #define t1 rhash_tiger_sboxes[0] 42 | #define t2 rhash_tiger_sboxes[1] 43 | #define t3 rhash_tiger_sboxes[2] 44 | #define t4 rhash_tiger_sboxes[3] 45 | 46 | #ifdef CPU_X64 /* for x86-64 */ 47 | #define round(a,b,c,x,mul) \ 48 | c ^= x; \ 49 | a -= t1[(uint8_t)(c)] ^ \ 50 | t2[(uint8_t)((c) >> (2 * 8))] ^ \ 51 | t3[(uint8_t)((c) >> (4 * 8))] ^ \ 52 | t4[(uint8_t)((c) >> (6 * 8))] ; \ 53 | b += t4[(uint8_t)((c) >> (1 * 8))] ^ \ 54 | t3[(uint8_t)((c) >> (3 * 8))] ^ \ 55 | t2[(uint8_t)((c) >> (5 * 8))] ^ \ 56 | t1[(uint8_t)((c) >> (7 * 8))]; \ 57 | b *= mul; 58 | 59 | #else /* for IA32 */ 60 | 61 | #define round(a,b,c,x,mul) \ 62 | c ^= x; \ 63 | a -= t1[(uint8_t)(c)] ^ \ 64 | t2[(uint8_t)(((uint32_t)(c)) >> (2 * 8))] ^ \ 65 | t3[(uint8_t)((c) >> (4 * 8))] ^ \ 66 | t4[(uint8_t)(((uint32_t)((c) >> (4 * 8))) >> (2 * 8))] ; \ 67 | b += t4[(uint8_t)(((uint32_t)(c)) >> (1 * 8))] ^ \ 68 | t3[(uint8_t)(((uint32_t)(c)) >> (3 * 8))] ^ \ 69 | t2[(uint8_t)(((uint32_t)((c) >> (4 * 8))) >> (1 * 8))] ^ \ 70 | t1[(uint8_t)(((uint32_t)((c) >> (4 * 8))) >> (3 * 8))]; \ 71 | b *= mul; 72 | #endif /* CPU_X64 */ 73 | 74 | #define pass(a,b,c,mul) \ 75 | round(a,b,c,x0,mul) \ 76 | round(b,c,a,x1,mul) \ 77 | round(c,a,b,x2,mul) \ 78 | round(a,b,c,x3,mul) \ 79 | round(b,c,a,x4,mul) \ 80 | round(c,a,b,x5,mul) \ 81 | round(a,b,c,x6,mul) \ 82 | round(b,c,a,x7,mul) 83 | 84 | #define key_schedule { \ 85 | x0 -= x7 ^ I64(0xA5A5B5A5A5A5A7A5); \ 86 | x1 ^= x0; \ 87 | x2 += x1; \ 88 | x3 -= x2 ^ ((~x1)<<19); \ 89 | x4 ^= x3; \ 90 | x5 += x4; \ 91 | x6 -= x5 ^ ((~x4)>>23); \ 92 | x7 ^= x6; \ 93 | x0 += x7; \ 94 | x1 -= x0 ^ ((~x7)<<19); \ 95 | x2 ^= x1; \ 96 | x3 += x2; \ 97 | x4 -= x3 ^ ((~x2)>>23); \ 98 | x5 ^= x4; \ 99 | x6 += x5; \ 100 | x7 -= x6 ^ I64(0x0123456789ABCDEF); \ 101 | } 102 | 103 | /** 104 | * The core transformation. Process a 512-bit block. 105 | * 106 | * @param state the algorithm state 107 | * @param block the message block to process 108 | */ 109 | static void rhash_tiger_process_block(uint64_t state[3], uint64_t* block) 110 | { 111 | /* Optimized for GCC IA32. 112 | The order of declarations is important for compiler. */ 113 | uint64_t a, b, c; 114 | uint64_t x0, x1, x2, x3, x4, x5, x6, x7; 115 | #ifndef CPU_X64 116 | uint64_t tmp; 117 | char i; 118 | #endif 119 | 120 | x0 = le2me_64(block[0]); 121 | x1 = le2me_64(block[1]); 122 | x2 = le2me_64(block[2]); 123 | x3 = le2me_64(block[3]); 124 | x4 = le2me_64(block[4]); 125 | x5 = le2me_64(block[5]); 126 | x6 = le2me_64(block[6]); 127 | x7 = le2me_64(block[7]); 128 | 129 | a = state[0]; 130 | b = state[1]; 131 | c = state[2]; 132 | 133 | /* passes and key shedules */ 134 | #ifndef CPU_X64 135 | for (i = 0; i < 3; i++) { 136 | if (i != 0) key_schedule; 137 | pass(a, b, c, (i == 0 ? 5 : i == 1 ? 7 : 9)); 138 | tmp = a; 139 | a = c; 140 | c = b; 141 | b = tmp; 142 | } 143 | #else 144 | pass(a, b, c, 5); 145 | key_schedule; 146 | pass(c, a, b, 7); 147 | key_schedule; 148 | pass(b, c, a, 9); 149 | #endif 150 | 151 | /* feedforward operation */ 152 | state[0] = a ^ state[0]; 153 | state[1] = b - state[1]; 154 | state[2] = c + state[2]; 155 | } 156 | 157 | /** 158 | * Calculate message hash. 159 | * Can be called repeatedly with chunks of the message to be hashed. 160 | * 161 | * @param ctx the algorithm context containing current hashing state 162 | * @param msg message chunk 163 | * @param size length of the message chunk 164 | */ 165 | void rhash_tiger_update(tiger_ctx *ctx, const unsigned char* msg, size_t size) 166 | { 167 | size_t index = (size_t)ctx->length & 63; 168 | ctx->length += size; 169 | 170 | /* fill partial block */ 171 | if (index) { 172 | size_t left = tiger_block_size - index; 173 | if (size < left) { 174 | memcpy(ctx->message + index, msg, size); 175 | return; 176 | } else { 177 | memcpy(ctx->message + index, msg, left); 178 | rhash_tiger_process_block(ctx->hash, (uint64_t*)ctx->message); 179 | msg += left; 180 | size -= left; 181 | } 182 | } 183 | while (size >= tiger_block_size) { 184 | if (IS_ALIGNED_64(msg)) { 185 | /* the most common case is processing of an already aligned message 186 | without copying it */ 187 | rhash_tiger_process_block(ctx->hash, (uint64_t*)msg); 188 | } else { 189 | memcpy(ctx->message, msg, tiger_block_size); 190 | rhash_tiger_process_block(ctx->hash, (uint64_t*)ctx->message); 191 | } 192 | 193 | msg += tiger_block_size; 194 | size -= tiger_block_size; 195 | } 196 | if (size) { 197 | /* save leftovers */ 198 | memcpy(ctx->message, msg, size); 199 | } 200 | } 201 | 202 | /** 203 | * Store calculated hash into the given array. 204 | * 205 | * @param ctx the algorithm context containing current hashing state 206 | * @param result calculated hash in binary form 207 | */ 208 | void rhash_tiger_final(tiger_ctx *ctx, unsigned char result[24]) 209 | { 210 | unsigned index = (unsigned)ctx->length & 63; 211 | uint64_t* msg64 = (uint64_t*)ctx->message; 212 | 213 | /* pad message and run for last block */ 214 | 215 | /* append the byte 0x01 to the message */ 216 | ctx->message[index++] = (ctx->tiger2 ? 0x80 : 0x01); 217 | 218 | /* if no room left in the message to store 64-bit message length */ 219 | if (index > 56) { 220 | /* then fill the rest with zeros and process it */ 221 | while (index < 64) { 222 | ctx->message[index++] = 0; 223 | } 224 | rhash_tiger_process_block(ctx->hash, msg64); 225 | index = 0; 226 | } 227 | while (index < 56) { 228 | ctx->message[index++] = 0; 229 | } 230 | msg64[7] = le2me_64(ctx->length << 3); 231 | rhash_tiger_process_block(ctx->hash, msg64); 232 | 233 | /* save result hash */ 234 | le64_copy(result, 0, &ctx->hash, 24); 235 | } 236 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | // 2 | //========================================================================= 3 | // 4 | // Filename: main.c 5 | // 6 | // Description: 7 | // 8 | // Version: 1.0 9 | // Created: 04/28/2018 05:10:20 A.M. 10 | // Revision: none 11 | // Compiler: gcc 12 | // 13 | // Author: codingstory, codingstory.tw@gmail.com 14 | // 15 | // 可从此文件了解 jmuSupplicant 的大致执行流程 16 | // 1、初始化用户输入参数 17 | // 2、检测是否后台已经有 jmuSupplicant 的实例正在运行 18 | // 3、初始化认证登录信息,用户名,密码,服务名等 19 | // 4、初始化网络设备,选择设备名,提取设备ip地址,netmask地址,MAC地址等信息 20 | // 5、配置 signal handler,为定时发送心跳包保持在线做准备 21 | // 6、初始化完毕,开始认证。发送 EAPOL START frame 给服务器请求认证登录, 22 | // 此为认证过程中第一个步骤 23 | // 7、捕获服务器返回的 Request EAP frames,用以执行后续认证操作。 24 | // 25 | //========================================================================= 26 | // 27 | 28 | #include 29 | #include 30 | 31 | #include "functions.h" 32 | #include "init.h" 33 | #include "eap_frames_operations.h" 34 | 35 | const static char LOCK_FILE_PATH[23] = "/var/run/test_lock.pid"; 36 | 37 | int fd = -1; // lock file descriptor 38 | 39 | static void ShowUsage() 40 | { 41 | printf( "\n" 42 | "jmuSupplicant for JMU \n" 43 | "\t -- Client for Ruijie Authentication in JMU campus.\n" 44 | "\n" 45 | " Usage:\n" 46 | "\t请使用 root 权限下运行。通常需要在命令行前加入 'sudo'。\n\n" 47 | "\t-u, --username 用户名,通常为学号。\n" 48 | "\t-p, --password 密码。\n" 49 | "\t-s, --service_company 服务名。\n" 50 | "\t 0(教育网),1(联通宽带接入),2(移动宽带接入),3(电信宽带接入) \n\n" 51 | "\n" 52 | " 可选参数:\n\n" 53 | // "\t-g, --gateway 指定 Gateway(网关) 地址。 \n\n" 54 | 55 | // "\t-d, --dns 指定 DNS 服务器地址。 \n\n" 56 | 57 | "\t--ip 指定 ip 地址,推荐配合 mignight 模式中使用。 \n\n" 58 | "\t--mask 指定 Netmask(子网遮罩) 地址。 \n\n" 59 | "\t--interface_card 指定 网卡名称,则程序中不再要求用户手动选择网卡\n\n" 60 | "\t-n 开启 midnight 模式,断网后使用。\n\n" 61 | 62 | "\t-b, --background 认证成功后,jmuSupplicant进入 dameon 模式,后台运行。\n\n" 63 | 64 | "\t-k 停止正在运行的 jmuSupplicant。\n\n" 65 | 66 | "\t-h, --help 展开 jmuSupplicant 运行帮助。\n\n" 67 | "\n" 68 | " 关于 jmuSupplicant:\n\n" 69 | "\tjmuSupplicant is a program developed individually by 入山 and release under Apache-v2.0 \n" 70 | "\tlicense as free software, with NO any relaiontship with Ruijie company.\n\n\n" 71 | 72 | // "\tAnother codingstory work. Blog: https://codingstory.com.cn\n" 73 | "\t\t\t\t\t\t\t\t2018.06.01\n"); 74 | } 75 | 76 | 77 | // 78 | //------function---------------------------------------------------------- 79 | // name: 80 | // InitArguments 81 | // description: 82 | // 获取 jmuSupplicant 运行时用户输入的参数 83 | //------------------------------------------------------------------------ 84 | // 85 | static void InitArguments(int *argc, char ***argv) 86 | { 87 | extern unsigned int background_running; // background running 88 | extern unsigned int multiple_running; // multiple running 89 | extern unsigned int midnight; // login after school network cut off 90 | extern unsigned int exit_flag; 91 | char *dev; // 连接的设备名 92 | extern char *username; 93 | extern char *password; 94 | extern char *user_input_gateway; // 由用户设定的四个报文参数 95 | extern char *user_input_dns; // numbers-and-dots dns notation by user input 96 | extern char *user_input_ipaddr; // numbers-and-dots ip notation by user input 97 | extern char *user_input_mask; // number-and-dots mask notation by user input 98 | extern char *service_company; // login service name 99 | extern char *network_interface_card_name; 100 | 101 | // Option struct for progrm run arguments 102 | static struct option long_options[] = { 103 | {"help", no_argument, 0, 'h'}, 104 | {"background", no_argument, &background_running, 1}, 105 | {"username", required_argument, 0, 'u'}, 106 | {"password", required_argument, 0, 'p'}, 107 | {"ip", required_argument, 0, 4}, 108 | {"mask", required_argument, 0, 5}, 109 | {"gateway", required_argument, 0, 'g'}, 110 | {"dns", required_argument, 0, 'd'}, 111 | {"service_company", required_argument, 0, 's'}, 112 | {"interface_card", required_argument, 0, 'i'}, 113 | {0, 0, 0, 0} 114 | }; 115 | int c; 116 | while (1) { 117 | 118 | /* getopt_long stores the option index here. */ 119 | int option_index = 0; 120 | c = getopt_long ((*argc), (*argv), "u:s:p:g:d:hbkmni", 121 | long_options, &option_index); 122 | if (c == -1) 123 | break; 124 | switch (c) { 125 | case 0: 126 | break; 127 | case 'b': 128 | background_running = 1; 129 | break; 130 | case 4: 131 | user_input_ipaddr = optarg; 132 | break; 133 | case 5: 134 | user_input_mask = optarg; 135 | break; 136 | case 'n': 137 | midnight = 1; 138 | break; 139 | case 'u': 140 | username = optarg; 141 | break; 142 | case 'p': 143 | password = optarg; 144 | break; 145 | case 'g': 146 | user_input_gateway = optarg; 147 | break; 148 | case 'd': 149 | user_input_dns = optarg; 150 | break; 151 | case 's': 152 | service_company = optarg; 153 | break; 154 | case 'k': 155 | exit_flag = 1; 156 | break; 157 | case 'm': 158 | multiple_running = 1; 159 | break; 160 | case 'i': 161 | network_interface_card_name = optarg; // 网络设备信息结构体,包含 ip, netmask, gateway 等等 162 | break; 163 | case 'h': 164 | ShowUsage(); 165 | exit(EXIT_SUCCESS); 166 | break; 167 | case '?': 168 | if (optopt == 'u' || optopt == 'p'|| 169 | optopt == 'g'|| optopt == 'd') 170 | fprintf (stderr, "选项 -%c 需要加入参数.\n", optopt); 171 | exit(EXIT_FAILURE); 172 | break; 173 | default: 174 | fprintf (stderr,"未知的选项 `\\x%x'.\n", c); 175 | exit(EXIT_FAILURE); 176 | } 177 | } 178 | 179 | return; 180 | } 181 | 182 | 183 | int main(int argc, char **argv) 184 | { 185 | pid_t pid; // running process pid 186 | extern unsigned int exit_flag; // 程序退出参数 187 | extern unsigned int multiple_running; // 允许程序多个process同时运行 188 | struct sigaction sa; // examine and change a signal action 189 | 190 | // O_CREAT, if the specified file does not exist, it will be created by open() 191 | // O_RDWR, access modes, read and write 192 | fd = open(LOCK_FILE_PATH, O_CREAT | O_RDWR); 193 | if (fd == -1) { 194 | fprintf(stderr, "Can't open or create the lock file\n"); 195 | exit(EXIT_FAILURE); 196 | } 197 | 198 | // 初始化用户输入参数 199 | InitArguments(&argc, &argv); 200 | 201 | // 检测是否后台已经有此程序的实例正在运行 202 | if(!multiple_running) { 203 | pid = LockTest(fd, F_WRLCK, 0, SEEK_SET, 0); 204 | initiative_exit_program_with_already_running_check(exit_flag, fd, pid); 205 | } 206 | 207 | // 初始化认证登录信息,用户名,密码,服务名等 208 | init_login_config(); 209 | // 初始化网络设备,选择网卡,提取网卡ip地址,netmask地址,MAC地址等信息 210 | init_device(); 211 | 212 | // 配置 signal handler,为定时发送心跳包保持在线做准备 213 | memset(&sa, 0, sizeof(sa)); 214 | sa.sa_handler = &HandleSigalrm; 215 | sigfillset(&sa.sa_mask); 216 | if(sigaction(SIGALRM, &sa, NULL) == -1) { 217 | fprintf(stderr, "Error: cannot handle SIGALRM."); 218 | } 219 | 220 | alarm(10); 221 | // 初始化完毕,开始认证。发送 EAP-START frame 给服务器请求认证登录, 222 | // 此为认证过程中第一个步骤 223 | send_eap_frame(EAPOL_START, NULL); 224 | 225 | // 捕获服务器返回的 EAP frames,用以执行后续认证操作。 226 | capture_eap_frames(); 227 | 228 | // 保持在线 229 | while(1) 230 | { 231 | sleep(20); 232 | KeepOnline(); 233 | } 234 | return 0; 235 | } 236 | 237 | -------------------------------------------------------------------------------- /src/mentohust_encryption/rjwhirlpool.c: -------------------------------------------------------------------------------- 1 | /* whirlpool.c - an implementation of the Whirlpool Hash Function. 2 | * 3 | * Copyright: 2009-2012 Aleksey Kravchenko 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! 15 | * 16 | * Documentation: 17 | * P. S. L. M. Barreto, V. Rijmen, ``The Whirlpool hashing function,'' 18 | * NESSIE submission, 2000 (tweaked version, 2001) 19 | * 20 | * The algorithm is named after the Whirlpool Galaxy in Canes Venatici. 21 | */ 22 | 23 | #include 24 | #include 25 | #include "byte_order.h" 26 | #include "rjwhirlpool.h" 27 | 28 | /** 29 | * Initialize context before calculaing hash. 30 | * 31 | * @param ctx context to initialize 32 | */ 33 | void rhash_whirlpool_init(struct whirlpool_ctx* ctx) 34 | { 35 | ctx->length = 0; 36 | //memset(ctx->hash, 0, sizeof(ctx->hash)); 37 | ctx->hash[0] = 0; 38 | ctx->hash[1] = 3; 39 | ctx->hash[2] = 5; 40 | ctx->hash[3] = 2; 41 | ctx->hash[4] = 1; 42 | ctx->hash[5] = 7; 43 | ctx->hash[6] = 4; 44 | ctx->hash[7] = 6; 45 | } 46 | 47 | /* Algorithm S-Box */ 48 | extern uint64_t rhash_whirlpool_sbox[8][256]; 49 | 50 | #define WHIRLPOOL_OP(src, shift) ( \ 51 | rhash_whirlpool_sbox[0][(int)(src[ shift & 7] >> 56) ] ^ \ 52 | rhash_whirlpool_sbox[1][(int)(src[(shift + 7) & 7] >> 48) & 0xff] ^ \ 53 | rhash_whirlpool_sbox[2][(int)(src[(shift + 6) & 7] >> 40) & 0xff] ^ \ 54 | rhash_whirlpool_sbox[3][(int)(src[(shift + 5) & 7] >> 32) & 0xff] ^ \ 55 | rhash_whirlpool_sbox[4][(int)(src[(shift + 4) & 7] >> 24) & 0xff] ^ \ 56 | rhash_whirlpool_sbox[5][(int)(src[(shift + 3) & 7] >> 16) & 0xff] ^ \ 57 | rhash_whirlpool_sbox[6][(int)(src[(shift + 2) & 7] >> 8) & 0xff] ^ \ 58 | rhash_whirlpool_sbox[7][(int)(src[(shift + 1) & 7] ) & 0xff]) 59 | 60 | /** 61 | * The core transformation. Process a 512-bit block. 62 | * 63 | * @param hash algorithm state 64 | * @param block the message block to process 65 | */ 66 | static void rhash_whirlpool_process_block(uint64_t *hash, uint64_t* p_block) 67 | { 68 | int i; /* loop counter */ 69 | uint64_t K[2][8]; /* key */ 70 | uint64_t state[2][8]; /* state */ 71 | 72 | /* alternating binary flags */ 73 | unsigned int m = 0; 74 | 75 | /* the number of rounds of the internal dedicated block cipher */ 76 | const int number_of_rounds = 10; 77 | 78 | /* array used in the rounds */ 79 | static const uint64_t rc[10] = { 80 | I64(0x1823c6e887b8014f), 81 | I64(0x36a6d2f5796f9152), 82 | I64(0x60bc9b8ea30c7b35), 83 | I64(0x1de0d7c22e4bfe57), 84 | I64(0x157737e59ff04ada), 85 | I64(0x58c9290ab1a06b85), 86 | I64(0xbd5d10f4cb3e0567), 87 | I64(0xe427418ba77d95d8), 88 | I64(0xfbee7c66dd17479e), 89 | I64(0xca2dbf07ad5a8333) 90 | }; 91 | 92 | /* map the message buffer to a block */ 93 | for (i = 0; i < 8; i++) { 94 | /* store K^0 and xor it with the intermediate hash state */ 95 | K[0][i] = hash[i]; /***********maybe k[0][8-i]**************/ 96 | state[0][i] = be2me_64(p_block[i]) ^ hash[i]; /****maybe state[0][8-i]****/ 97 | hash[i] = state[0][i]; /**************maybe disapeared********/ 98 | } 99 | 100 | 101 | /* iterate over algorithm rounds */ 102 | for (i = 0; i < number_of_rounds; i++) { 103 | /* compute K^i from K^{i-1} */ 104 | K[m ^ 1][0] = WHIRLPOOL_OP(K[m], 0) ^ rc[i]; 105 | K[m ^ 1][1] = WHIRLPOOL_OP(K[m], 1); 106 | K[m ^ 1][2] = WHIRLPOOL_OP(K[m], 2); 107 | K[m ^ 1][3] = WHIRLPOOL_OP(K[m], 3); 108 | K[m ^ 1][4] = WHIRLPOOL_OP(K[m], 4); 109 | K[m ^ 1][5] = WHIRLPOOL_OP(K[m], 5); 110 | K[m ^ 1][6] = WHIRLPOOL_OP(K[m], 6); 111 | K[m ^ 1][7] = WHIRLPOOL_OP(K[m], 7); 112 | 113 | /* apply the i-th round transformation */ 114 | //state[m ^ 1][0] = WHIRLPOOL_OP(state[m], 0) ^ K[m ^ 1][0]; 115 | state[m ^ 1][0] = WHIRLPOOL_OP(state[m], 0) ^ K[m ^ 1][0]; 116 | state[m ^ 1][1] = (WHIRLPOOL_OP(state[m], 1) ^ K[m ^ 1][1]); 117 | state[m ^ 1][2] = (WHIRLPOOL_OP(state[m], 2) ^ K[m ^ 1][2]) + 1; 118 | state[m ^ 1][3] = (WHIRLPOOL_OP(state[m], 3) ^ K[m ^ 1][3]); 119 | state[m ^ 1][4] = (WHIRLPOOL_OP(state[m], 4) ^ K[m ^ 1][4]); 120 | state[m ^ 1][5] = (WHIRLPOOL_OP(state[m], 5) ^ K[m ^ 1][5]) + 1; 121 | state[m ^ 1][6] = (WHIRLPOOL_OP(state[m], 6) ^ K[m ^ 1][6]) + 1; 122 | state[m ^ 1][7] = (WHIRLPOOL_OP(state[m], 7) ^ K[m ^ 1][7]); 123 | 124 | m = m ^ 1; 125 | } 126 | 127 | /* apply the Miyaguchi-Preneel compression function */ 128 | hash[0] ^= state[0][0]; 129 | hash[1] ^= state[0][1]; 130 | hash[2] ^= state[0][2]; 131 | hash[3] ^= state[0][3]; 132 | hash[4] ^= state[0][4]; 133 | hash[5] ^= state[0][5]; 134 | hash[6] ^= state[0][6]; 135 | hash[7] ^= state[0][7]; 136 | } 137 | 138 | /** 139 | * Calculate message hash. 140 | * Can be called repeatedly with chunks of the message to be hashed. 141 | * 142 | * @param ctx the algorithm context containing current hashing state 143 | * @param msg message chunk 144 | * @param size length of the message chunk 145 | */ 146 | void rhash_whirlpool_update(whirlpool_ctx *ctx, const unsigned char* msg, size_t size) 147 | { 148 | unsigned index = (unsigned)ctx->length & 63; 149 | unsigned left; 150 | ctx->length += size; 151 | 152 | /* fill partial block */ 153 | if (index) { 154 | left = whirlpool_block_size - index; 155 | memcpy(ctx->message + index, msg, (size < left ? size : left)); 156 | if (size < left) return; 157 | 158 | /* process partial block */ 159 | rhash_whirlpool_process_block(ctx->hash, (uint64_t*)ctx->message); 160 | msg += left; 161 | size -= left; 162 | } 163 | while (size >= whirlpool_block_size) { 164 | uint64_t* aligned_message_block; 165 | if (IS_ALIGNED_64(msg)) { 166 | /* the most common case is processing of an already aligned message 167 | without copying it */ 168 | aligned_message_block = (uint64_t*)msg; 169 | } else { 170 | memcpy(ctx->message, msg, whirlpool_block_size); 171 | aligned_message_block = (uint64_t*)ctx->message; 172 | } 173 | 174 | rhash_whirlpool_process_block(ctx->hash, aligned_message_block); 175 | msg += whirlpool_block_size; 176 | size -= whirlpool_block_size; 177 | } 178 | if (size) { 179 | /* save leftovers */ 180 | memcpy(ctx->message, msg, size); 181 | } 182 | } 183 | 184 | /** 185 | * Store calculated hash into the given array. 186 | * 187 | * @param ctx the algorithm context containing current hashing state 188 | * @param result calculated hash in binary form 189 | */ 190 | void rhash_whirlpool_final(whirlpool_ctx *ctx, unsigned char* result) 191 | { 192 | unsigned index = (unsigned)ctx->length & 63; 193 | uint64_t* msg64 = (uint64_t*)ctx->message; 194 | 195 | /* pad message and run for last block */ 196 | ctx->message[index++] = 0x80; 197 | 198 | /* if no room left in the message to store 256-bit message length */ 199 | if (index > 32) { 200 | /* then pad the rest with zeros and process it */ 201 | while (index < 64) { 202 | ctx->message[index++] = 0; 203 | } 204 | rhash_whirlpool_process_block(ctx->hash, msg64); 205 | index = 0; 206 | } 207 | /* due to optimization actually only 64-bit of message length are stored */ 208 | while (index < 56) { 209 | ctx->message[index++] = 0; 210 | } 211 | msg64[7] = be2me_64(ctx->length << 3); 212 | rhash_whirlpool_process_block(ctx->hash, msg64); 213 | 214 | /* save result hash */ 215 | be64_copy(result, 0, ctx->hash, 64); 216 | } 217 | -------------------------------------------------------------------------------- /src/mentohust_encryption/rjmd5.c: -------------------------------------------------------------------------------- 1 | /* md5.c - an implementation of the MD5 algorithm, based on RFC 1321. 2 | * 3 | * Copyright: 2007-2012 Aleksey Kravchenko 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! 15 | */ 16 | 17 | #include 18 | #include "byte_order.h" 19 | #include "rjmd5.h" 20 | 21 | /** 22 | * Initialize context before calculaing hash. 23 | * 24 | * @param ctx context to initialize 25 | */ 26 | void rhash_md5_init(md5_ctx *ctx) 27 | { 28 | ctx->length = 0; 29 | 30 | /* initialize state */ 31 | ctx->hash[0] = 0x50137246; 32 | ctx->hash[1] = 0x8acf9dbe; 33 | ctx->hash[2] = 0xc9efaced; 34 | ctx->hash[3] = 0x25647013; 35 | } 36 | 37 | /* First, define four auxiliary functions that each take as input 38 | * three 32-bit words and returns a 32-bit word.*/ 39 | 40 | /* F(x,y,z) = ((y XOR z) AND x) XOR z - is faster then original version */ 41 | #define MD5_F(x, y, z) ((((y) ^ (z)) & (x)) ^ (z)) 42 | #define MD5_G(x, y, z) (((x) & (z)) | ((y) & (~z))) 43 | #define MD5_H(x, y, z) ((x) ^ (y) ^ (z)) 44 | #define MD5_I(x, y, z) ((y) ^ ((x) | (~z))) 45 | 46 | /* transformations for rounds 1, 2, 3, and 4. */ 47 | #define MD5_ROUND1(a, b, c, d, x, s, ac) { \ 48 | (a) += MD5_F((b), (c), (d)) + (x) + (ac); \ 49 | (a) = ROTL32((a), (s)); \ 50 | (a) += (b) + 2; \ 51 | } 52 | #define MD5_ROUND2(a, b, c, d, x, s, ac) { \ 53 | (a) += MD5_G((b), (c), (d)) + (x) + (ac); \ 54 | (a) = ROTL32((a), (s)); \ 55 | (a) += (b) - 2; \ 56 | } 57 | #define MD5_ROUND3(a, b, c, d, x, s, ac) { \ 58 | (a) += MD5_H((b), (c), (d)) + (x) + (ac); \ 59 | (a) = ROTL32((a), (s)); \ 60 | (a) += (b) - 1; \ 61 | } 62 | #define MD5_ROUND4(a, b, c, d, x, s, ac) { \ 63 | (a) += MD5_I((b), (c), (d)) + (x) + (ac); \ 64 | (a) = ROTL32((a), (s)); \ 65 | (a) += (b) + 1; \ 66 | } 67 | 68 | /** 69 | * The core transformation. Process a 512-bit block. 70 | * The function has been taken from RFC 1321 with little changes. 71 | * 72 | * @param state algorithm state 73 | * @param x the message block to process 74 | */ 75 | static void rhash_md5_process_block(unsigned state[4], const unsigned* x) 76 | { 77 | register unsigned a, b, c, d; 78 | a = state[0]; 79 | b = state[1]; 80 | c = state[2]; 81 | d = state[3]; 82 | 83 | MD5_ROUND1(a, b, c, d, x[ 0], 7, 0xd76aa478); 84 | MD5_ROUND1(d, a, b, c, x[ 1], 12, 0xe8c7b756); 85 | MD5_ROUND1(c, d, a, b, x[ 2], 17, 0x242070db); 86 | MD5_ROUND1(b, c, d, a, x[ 3], 22, 0xc1bdceee); 87 | MD5_ROUND1(a, b, c, d, x[ 4], 7, 0xf57c0faf); 88 | MD5_ROUND1(d, a, b, c, x[ 5], 12, 0x4787c62a); 89 | MD5_ROUND1(c, d, a, b, x[ 6], 17, 0xa8304613); 90 | MD5_ROUND1(b, c, d, a, x[ 7], 22, 0xfd469501); 91 | MD5_ROUND1(a, b, c, d, x[ 8], 7, 0x698098d8); 92 | MD5_ROUND1(d, a, b, c, x[ 9], 12, 0x8b44f7af); 93 | MD5_ROUND1(c, d, a, b, x[10], 17, 0xffff5bb1); 94 | MD5_ROUND1(b, c, d, a, x[11], 22, 0x895cd7be); 95 | MD5_ROUND1(a, b, c, d, x[12], 7, 0x6b901122); 96 | MD5_ROUND1(d, a, b, c, x[13], 12, 0xfd987163); 97 | MD5_ROUND1(c, d, a, b, x[14], 17, 0xa679438e); 98 | MD5_ROUND1(b, c, d, a, x[15], 22, 0x49b40821); 99 | 100 | MD5_ROUND2(a, b, c, d, x[ 1], 5, 0xf61e2562); 101 | MD5_ROUND2(d, a, b, c, x[ 6], 9, 0xc040b340); 102 | MD5_ROUND2(c, d, a, b, x[11], 14, 0x265e5a51); 103 | MD5_ROUND2(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); 104 | MD5_ROUND2(a, b, c, d, x[ 5], 5, 0xd62f105d); 105 | MD5_ROUND2(d, a, b, c, x[10], 9, 0x02442453); 106 | MD5_ROUND2(c, d, a, b, x[15], 14, 0xd8a1e681); 107 | MD5_ROUND2(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); 108 | MD5_ROUND2(a, b, c, d, x[ 9], 5, 0x21e1cde6); 109 | MD5_ROUND2(d, a, b, c, x[14], 9, 0xc33707d6); 110 | MD5_ROUND2(c, d, a, b, x[ 3], 14, 0xf4d50d87); 111 | MD5_ROUND2(b, c, d, a, x[ 8], 20, 0x455a14ed); 112 | MD5_ROUND2(a, b, c, d, x[13], 5, 0xa9e3e905); 113 | MD5_ROUND2(d, a, b, c, x[ 2], 9, 0xfcefa3f8); 114 | MD5_ROUND2(c, d, a, b, x[ 7], 14, 0x676f02d9); 115 | MD5_ROUND2(b, c, d, a, x[12], 20, 0x8d2a4c8a); 116 | 117 | MD5_ROUND3(a, b, c, d, x[ 5], 5, 0xfffa3492); 118 | MD5_ROUND3(d, a, b, c, x[ 8], 11, 0x8771f681); 119 | MD5_ROUND3(c, d, a, b, x[11], 16, 0x6d9d6122); 120 | MD5_ROUND3(b, c, d, a, x[14], 23, 0xfde5380c); 121 | MD5_ROUND3(a, b, c, d, x[ 1], 5, 0xa4beea44); 122 | MD5_ROUND3(d, a, b, c, x[ 4], 11, 0x4bdecfa9); 123 | MD5_ROUND3(c, d, a, b, x[ 7], 16, 0xf6bb4b60); 124 | MD5_ROUND3(b, c, d, a, x[10], 23, 0xbebfbc70); 125 | MD5_ROUND3(a, b, c, d, x[13], 5, 0x289b7ec6); 126 | MD5_ROUND3(d, a, b, c, x[ 0], 11, 0xeaa127fa); 127 | MD5_ROUND3(c, d, a, b, x[ 3], 16, 0xd4ef3085); 128 | MD5_ROUND3(b, c, d, a, x[ 6], 23, (uint8_t)(x[2] >> 8) + 0x4881d05); 129 | MD5_ROUND3(a, b, c, d, x[ 9], 5, 0xd9d4d039); 130 | MD5_ROUND3(d, a, b, c, x[12], 11, 0xe6db99e5); 131 | MD5_ROUND3(c, d, a, b, x[15], 16, 0x1fa27cf8); 132 | MD5_ROUND3(b, c, d, a, x[ 2], 23, 0xc4ac5665); 133 | 134 | MD5_ROUND4(a, b, c, d, x[ 0], 6, 0xf4292244); 135 | MD5_ROUND4(d, a, b, c, x[ 7], 10, 0x432aff97); 136 | MD5_ROUND4(c, d, a, b, x[14], 15, 0xab9423a7); 137 | MD5_ROUND4(b, c, d, a, x[ 5], 19, 0xfc93a039); 138 | MD5_ROUND4(a, b, c, d, x[12], 6, 0x655659c3); 139 | MD5_ROUND4(d, a, b, c, x[ 3], 10, 0x8f0ccc92); 140 | MD5_ROUND4(c, d, a, b, x[10], 15, 0xffeff47d); 141 | MD5_ROUND4(b, c, d, a, x[ 1], 19, 0x85845dd1); 142 | MD5_ROUND4(a, b, c, d, x[ 8], 6, 0x6fa87e4f); 143 | MD5_ROUND4(d, a, b, c, x[15], 10, 0xfe2ce6e0); 144 | MD5_ROUND4(c, d, a, b, x[ 6], 15, 0xa3014314); 145 | MD5_ROUND4(b, c, d, a, x[13], 19, 0x4e0811a1); 146 | MD5_ROUND4(a, b, c, d, x[ 4], 6, 0xf7537e82); 147 | MD5_ROUND4(d, a, b, c, x[11], 10, 0xbd3af335); 148 | MD5_ROUND4(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); 149 | MD5_ROUND4(b, c, d, a, x[ 9], 19, 0xeb866391); 150 | 151 | state[0] += a; 152 | state[1] += b; 153 | state[2] += c; 154 | state[3] += d; 155 | } 156 | 157 | /** 158 | * Calculate message hash. 159 | * Can be called repeatedly with chunks of the message to be hashed. 160 | * 161 | * @param ctx the algorithm context containing current hashing state 162 | * @param msg message chunk 163 | * @param size length of the message chunk 164 | */ 165 | void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size) 166 | { 167 | unsigned index = (unsigned)ctx->length & 63; 168 | ctx->length += size; 169 | 170 | /* fill partial block */ 171 | if (index) { 172 | unsigned left = md5_block_size - index; 173 | le32_copy((char*)ctx->message, index, msg, (size < left ? size : left)); 174 | if (size < left) return; 175 | 176 | /* process partial block */ 177 | rhash_md5_process_block(ctx->hash, ctx->message); 178 | msg += left; 179 | size -= left; 180 | } 181 | while (size >= md5_block_size) { 182 | unsigned* aligned_message_block; 183 | if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg)) { 184 | /* the most common case is processing a 32-bit aligned message 185 | on a little-endian CPU without copying it */ 186 | aligned_message_block = (unsigned*)msg; 187 | } else { 188 | le32_copy(ctx->message, 0, msg, md5_block_size); 189 | aligned_message_block = ctx->message; 190 | } 191 | 192 | rhash_md5_process_block(ctx->hash, aligned_message_block); 193 | msg += md5_block_size; 194 | size -= md5_block_size; 195 | } 196 | if (size) { 197 | /* save leftovers */ 198 | le32_copy(ctx->message, 0, msg, size); 199 | } 200 | } 201 | 202 | /** 203 | * Store calculated hash into the given array. 204 | * 205 | * @param ctx the algorithm context containing current hashing state 206 | * @param result calculated hash in binary form 207 | */ 208 | void rhash_md5_final(md5_ctx *ctx, unsigned char* result) 209 | { 210 | unsigned index = ((unsigned)ctx->length & 63) >> 2; 211 | unsigned shift = ((unsigned)ctx->length & 3) * 8; 212 | 213 | /* pad message and run for last block */ 214 | 215 | /* append the byte 0x80 to the message */ 216 | ctx->message[index] &= ~(0xFFFFFFFF << shift); 217 | ctx->message[index++] ^= 0x80 << shift; 218 | 219 | /* if no room left in the message to store 64-bit message length */ 220 | if (index > 14) { 221 | /* then fill the rest with zeros and process it */ 222 | while (index < 16) { 223 | ctx->message[index++] = 0; 224 | } 225 | rhash_md5_process_block(ctx->hash, ctx->message); 226 | index = 0; 227 | } 228 | while (index < 14) { 229 | ctx->message[index++] = 0; 230 | } 231 | ctx->message[14] = (unsigned)(ctx->length << 3); 232 | ctx->message[15] = (unsigned)(ctx->length >> 29); 233 | rhash_md5_process_block(ctx->hash, ctx->message); 234 | 235 | if (result) le32_copy(result, 0, &ctx->hash, 16); 236 | } -------------------------------------------------------------------------------- /src/mentohust_encryption/mento_md5.c: -------------------------------------------------------------------------------- 1 | /* MD5.c - an implementation of md5 algorithm */ 2 | 3 | /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 4 | rights reserved. 5 | License to copy and use this software is granted provided that it 6 | is identified as the "RSA Data Security, Inc. MD5 Message-Digest 7 | Algorithm" in all material mentioning or referencing this software 8 | or this function. 9 | License is also granted to make and use derivative works provided 10 | that such works are identified as "derived from the RSA Data 11 | Security, Inc. MD5 Message-Digest Algorithm" in all material 12 | mentioning or referencing the derived work. 13 | RSA Data Security, Inc. makes no representations concerning either 14 | the merchantability of this software or the suitability of this 15 | software for any particular purpose. It is provided "as is" 16 | without express or implied warranty of any kind. 17 | These notices must be retained in any copies of any part of this 18 | documentation and/or software. 19 | */ 20 | #include "mento_md5.h" 21 | #include 22 | 23 | /* Constants for MD5Transform routine. */ 24 | #define S11 7 25 | #define S12 12 26 | #define S13 17 27 | #define S14 22 28 | #define S21 5 29 | #define S22 9 30 | #define S23 14 31 | #define S24 20 32 | #define S31 4 33 | #define S32 11 34 | #define S33 16 35 | #define S34 23 36 | #define S41 6 37 | #define S42 10 38 | #define S43 15 39 | #define S44 21 40 | 41 | static void MD5Transform(UINT4 [4], UCHAR [64]); 42 | static void Encode(UCHAR *, UINT4 *, UINT4); 43 | static void Decode(UINT4 *, UCHAR *, UINT4); 44 | 45 | static UCHAR PADDING[64] = { 46 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 49 | }; 50 | 51 | /* F, G, H and I are basic MD5 functions. 52 | */ 53 | #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 54 | #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 55 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 56 | #define I(x, y, z) ((y) ^ ((x) | (~z))) 57 | 58 | /* ROTATE_LEFT rotates x left n bits. 59 | */ 60 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 61 | 62 | /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 63 | Rotation is separate from addition to prevent recomputation. 64 | */ 65 | #define FF(a, b, c, d, x, s, ac) { \ 66 | (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 67 | (a) = ROTATE_LEFT ((a), (s)); \ 68 | (a) += (b); \ 69 | } 70 | #define GG(a, b, c, d, x, s, ac) { \ 71 | (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 72 | (a) = ROTATE_LEFT ((a), (s)); \ 73 | (a) += (b); \ 74 | } 75 | #define HH(a, b, c, d, x, s, ac) { \ 76 | (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 77 | (a) = ROTATE_LEFT ((a), (s)); \ 78 | (a) += (b); \ 79 | } 80 | #define II(a, b, c, d, x, s, ac) { \ 81 | (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 82 | (a) = ROTATE_LEFT ((a), (s)); \ 83 | (a) += (b); \ 84 | } 85 | 86 | /* MD5 initialization. Begins an MD5 operation, writing a new context. 87 | */ 88 | void MD5Init (MD5_CTX * context) 89 | 90 | { 91 | context->count[0] = context->count[1] = 0; 92 | /* Load magic initialization constants. 93 | */ 94 | context->state[0] = 0x67452301; 95 | context->state[1] = 0xefcdab89; 96 | context->state[2] = 0x98badcfe; 97 | context->state[3] = 0x10325476; 98 | } 99 | 100 | /* MD5 block update operation. Continues an MD5 message-digest 101 | operation, processing another message block, and updating the 102 | context. 103 | */ 104 | void MD5Update (MD5_CTX *context, UCHAR *input, UINT4 inputLen) 105 | 106 | { 107 | UINT4 i, index, partLen; 108 | 109 | /* Compute number of bytes mod 64 */ 110 | index = (UINT4)((context->count[0] >> 3) & 0x3F); 111 | 112 | /* Update number of bits */ 113 | if ((context->count[0] += ((UINT4)inputLen << 3)) 114 | < ((UINT4)inputLen << 3)) 115 | context->count[1]++; 116 | context->count[1] += ((UINT4)inputLen >> 29); 117 | 118 | partLen = 64 - index; 119 | 120 | /* Transform as many times as possible. 121 | */ 122 | if (inputLen >= partLen) { 123 | memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); 124 | MD5Transform (context->state, context->buffer); 125 | 126 | for (i = partLen; i + 63 < inputLen; i += 64) 127 | MD5Transform (context->state, &input[i]); 128 | 129 | index = 0; 130 | } else 131 | i = 0; 132 | 133 | /* Buffer remaining input */ 134 | memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],inputLen-i); 135 | } 136 | 137 | /* MD5 finalization. Ends an MD5 message-digest operation, writing the 138 | the message digest and zeroizing the context. 139 | */ 140 | void MD5Final (UCHAR digest[16], MD5_CTX *context) 141 | { 142 | UCHAR bits[8]; 143 | UINT4 index, padLen; 144 | 145 | /* Save number of bits */ 146 | Encode (bits, context->count, 8); 147 | 148 | /* Pad out to 56 mod 64. 149 | */ 150 | index = (UINT4)((context->count[0] >> 3) & 0x3f); 151 | padLen = (index < 56) ? (56 - index) : (120 - index); 152 | MD5Update (context, PADDING, padLen); 153 | 154 | /* Append length (before padding) */ 155 | MD5Update (context, bits, 8); 156 | 157 | /* Store state in digest */ 158 | Encode (digest, context->state, 16); 159 | 160 | /* Zeroize sensitive information. 161 | */ 162 | memset ((POINTER)context, 0, sizeof (*context)); 163 | } 164 | 165 | /* MD5 basic transformation. Transforms state based on block. 166 | */ 167 | static void MD5Transform (UINT4 state[4],UCHAR block[64]) 168 | { 169 | UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 170 | 171 | Decode (x, block, 64); 172 | 173 | /* Round 1 */ 174 | FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 175 | FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 176 | FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 177 | FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 178 | FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 179 | FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 180 | FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 181 | FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 182 | FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 183 | FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 184 | FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 185 | FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 186 | FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 187 | FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 188 | FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 189 | FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 190 | 191 | /* Round 2 */ 192 | GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 193 | GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 194 | GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 195 | GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 196 | GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 197 | GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 198 | GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 199 | GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 200 | GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 201 | GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 202 | GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 203 | GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 204 | GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 205 | GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 206 | GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 207 | GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 208 | 209 | /* Round 3 */ 210 | HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 211 | HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 212 | HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 213 | HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 214 | HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 215 | HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 216 | HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 217 | HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 218 | HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 219 | HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 220 | HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 221 | HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 222 | HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 223 | HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 224 | HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 225 | HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 226 | 227 | /* Round 4 */ 228 | II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 229 | II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 230 | II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 231 | II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 232 | II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 233 | II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 234 | II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 235 | II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 236 | II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 237 | II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 238 | II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 239 | II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 240 | II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 241 | II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 242 | II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 243 | II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 244 | 245 | state[0] += a; 246 | state[1] += b; 247 | state[2] += c; 248 | state[3] += d; 249 | 250 | /* Zeroize sensitive information. 251 | */ 252 | memset ((POINTER)x, 0, sizeof (x)); 253 | } 254 | 255 | /* Encodes input (UINT4) into output (UCHAR). Assumes len is 256 | a multiple of 4. 257 | */ 258 | static void Encode (UCHAR *output, UINT4 *input, UINT4 len) 259 | { 260 | UINT4 i, j; 261 | 262 | for (i = 0, j = 0; j < len; i++, j += 4) { 263 | output[j] = (UCHAR)(input[i] & 0xff); 264 | output[j+1] = (UCHAR)((input[i] >> 8) & 0xff); 265 | output[j+2] = (UCHAR)((input[i] >> 16) & 0xff); 266 | output[j+3] = (UCHAR)((input[i] >> 24) & 0xff); 267 | } 268 | } 269 | 270 | /* Decodes input (UCHAR) into output (UINT4). Assumes len is 271 | a multiple of 4. 272 | */ 273 | static void Decode (UINT4 *output, UCHAR *input, UINT4 len) 274 | { 275 | UINT4 i, j; 276 | 277 | for (i = 0, j = 0; j < len; i++, j += 4) 278 | output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 279 | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 280 | } 281 | 282 | /*Compute the md5sum (return static-local-variable),whose length is 16 bytes.*/ 283 | UCHAR* ComputeHash(UCHAR* src, UINT4 len) 284 | { 285 | MD5_CTX context; 286 | static UCHAR digest[16]; 287 | MD5Init(&context); 288 | MD5Update(&context, src, len); 289 | MD5Final(digest, &context); 290 | return digest; 291 | } 292 | 293 | 294 | -------------------------------------------------------------------------------- /src/eap_frames_operations.c: -------------------------------------------------------------------------------- 1 | // 2 | //========================================================================= 3 | // 4 | // Filename: eap_frames_operation.c 5 | // 6 | // Description: 7 | // 8 | // Version: 1.0 9 | // Created: 04/29/2018 08:58:12 P.M. 10 | // Revision: none 11 | // Compiler: gcc 12 | // 13 | // Author: codingstory, codingstory.tw@gmail.com 14 | // 15 | // 1、从网络设备捕获 EAP frame 16 | // 2、判断捕获的 Request EAP frame type。 17 | // 3、发送与之对应的 EAP RESPONSE frame 给服务器进行后续的认证。 18 | // 19 | // 20 | //========================================================================= 21 | // 22 | 23 | #include "eap_frames_operations.h" 24 | 25 | uint8_t eapol_start[1000]; // eapol start frame 26 | uint8_t eap_response_identity[1000]; 27 | uint8_t eap_response_md5_challenge[1000]; 28 | uint8_t eapol_heartbeat[45]; 29 | pcap_t *descr = NULL;// PCAP packet capture descriptor for the specified interface. 30 | SEND_FRAME_TYPE current_state; 31 | unsigned int midnight_mode_change_tail_data = 0; 32 | extern NIC_STRUCT nic_info; 33 | 34 | // 35 | //------function---------------------------------------------------------- 36 | // name: 37 | // capture_eap_frames 38 | // description: 39 | // 不断监听网络设备。从捕获到的数据包中,筛选出 EAP frame 40 | //------------------------------------------------------------------------ 41 | // 42 | int capture_eap_frames() 43 | { 44 | char pcap_errbuf[PCAP_ERRBUF_SIZE]; 45 | //pcap_t *descr; 46 | const uint8_t *frame; 47 | struct pcap_pkthdr hdr; // pcap.h 48 | struct ether_header *eptr; // net/ethernet.h 49 | struct bpf_program fp; // hold compiled program 50 | bpf_u_int32 netmask = nic_info.netmask.s_addr; // the netmask of our sniffing device 51 | char filter_exp[256]; // pcap_compile() filter parameter 52 | // 作为参数传递给 pcap_compile() 函数,指定从捕获到的数据包中筛选 EAP Frame 53 | const char filter_exp_format[] = "ether[12:2]=0x888e and ether dst %02X:%02X:%02X:%02X:%02X:%02X"; 54 | 55 | // Open a PCAP packet capture descriptor for the specified interface. 56 | descr = pcap_open_live(nic_info.nic_name, SNAP_LENGTH, 0, -1, pcap_errbuf); 57 | if(descr == NULL) { 58 | fprintf(stderr, "%s", pcap_errbuf); 59 | 60 | return -1; 61 | } 62 | 63 | // compile the program, filter frames which contains ethernet interface MAC address 64 | snprintf(filter_exp, sizeof(filter_exp),filter_exp_format, 65 | nic_info.nic_MAC[0], nic_info.nic_MAC[1], nic_info.nic_MAC[2], 66 | nic_info.nic_MAC[3], nic_info.nic_MAC[4], nic_info.nic_MAC[5]); // FILTER_STR ether[12:2] = 0x888e and ether dst "ether interface MAC" 67 | 68 | #if defined(DEBUG) 69 | printf("filter_exp_format is : %s\n", filter_exp_format); 70 | printf("filter_exp is : %s\n", filter_exp); 71 | #endif 72 | 73 | if(pcap_compile(descr, &fp, filter_exp, 0, netmask) == -1) { 74 | fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(descr)); 75 | 76 | return -1; 77 | } 78 | if(pcap_setfilter(descr, &fp) == -1) { 79 | fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(descr)); 80 | 81 | return -1; 82 | } 83 | 84 | // stratring sniff eap frames 85 | // 根据捕获到的服务器发送的不同类型的 Request EAP Frame,回应对应的 EAP frame 用以认证 86 | pcap_loop(descr, -1, determine_eap_frame_type_then_response_eap_frame, NULL); 87 | 88 | // CLose the PCAP descriptor 89 | pcap_close(descr); 90 | 91 | return 0; 92 | } 93 | 94 | // 95 | //------function---------------------------------------------------------- 96 | // name: 97 | // determine_eap_frame_type_then_response_eap_frame 98 | // description: 99 | // 提取 Request EAP frame 中的 EAP TYPE 数据, 以确定此 EAP frame type 100 | // 101 | //------------------------------------------------------------------------ 102 | // 103 | static void determine_eap_frame_type_then_response_eap_frame(u_char *args, const struct pcap_pkthdr* header, const uint8_t *frame) 104 | { 105 | 106 | #if defined(DEBUG) 107 | printf("EAP TYPE KEY VALUE is: %02x %02x\n", frame[22], frame[18]); 108 | #endif 109 | 110 | // type request identity 111 | if(frame[22] == 0x01 && frame[18] == 0x01) { 112 | type_req_idnty_action(frame); 113 | 114 | // type request md5 challenge 115 | } else if(frame[22] == 0x04 && frame[18] == 0x01) { 116 | type_req_md5_chg_action(frame); 117 | 118 | // type eap failure 119 | } else if(frame[18] == 0x04) { 120 | type_failure_action(frame); 121 | 122 | // type eap success 123 | } else if(frame[18] == 0x03) { 124 | // type_success_action(frame); 125 | type_success_action(frame); 126 | 127 | } else { 128 | type_error_action(); 129 | } 130 | 131 | return; 132 | } 133 | 134 | static void type_req_idnty_action(const uint8_t *frame) 135 | { 136 | current_state = EAP_REQUEST_IDENTITY; 137 | send_eap_frame(EAP_REQUEST_IDENTITY, frame); 138 | 139 | return; 140 | } 141 | 142 | static void type_req_md5_chg_action(const uint8_t *frame) 143 | { 144 | current_state = EAP_REQUEST_MD5_CHALLENGE; 145 | send_eap_frame(EAP_REQUEST_MD5_CHALLENGE, frame); 146 | 147 | return; 148 | } 149 | 150 | static void type_failure_action(const uint8_t *frame) 151 | { 152 | fprintf(stderr, "receive failure packet from server\n"); 153 | current_state = EAP_FAILURE; 154 | print_server_info(frame); 155 | // print_notification_msg(frame); 156 | // Logs here 157 | openlog(NULL, LOG_PID|LOG_CONS, LOG_USER); 158 | syslog(LOG_INFO, "Receive eap failure frame, program terminating..."); 159 | closelog(); 160 | 161 | if(relogin_when_receive_failure_frame() != 0) 162 | { 163 | fprintf(stdout, "Attemp to relogin after program received failure frame failed.\n"); 164 | exit(1); 165 | } 166 | 167 | 168 | return; 169 | } 170 | 171 | static void type_success_action(const uint8_t *frame) 172 | { 173 | extern unsigned int background_running; 174 | extern unsigned int midnight; 175 | extern int fd; // lock file descriptor 176 | 177 | current_state = ONLINE; 178 | print_server_info(frame); 179 | // print_notification_msg(frame); 180 | send_eap_frame(EAP_SUCCESS, frame); 181 | 182 | // 如果仅是后台运行,不是midnight模式后台运行的话 183 | if(!midnight && background_running) { 184 | 185 | daemon(1, 0); // create child process force the program running on background 186 | if(LockRegister(fd, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) == -1) { 187 | fprintf(stderr, "Lock file failed\n"); 188 | exit(EXIT_FAILURE); 189 | } else { 190 | fprintf(stdout, "Lock file success\n"); 191 | } 192 | 193 | // pcap_breakloop(descr); 194 | } 195 | 196 | // midnight 模式, 重新登录保持长时间不断线 197 | if(midnight == 1) 198 | { 199 | midnight_relogin(); 200 | 201 | }else pcap_breakloop(descr); // exit pcap capture process 202 | 203 | return; 204 | } 205 | 206 | static void type_error_action() 207 | { 208 | current_state = ERROR; 209 | fprintf(stderr, "Error eap type\n"); 210 | 211 | exit(1); 212 | } 213 | 214 | 215 | 216 | //------function---------------------------------------------------------- 217 | // name: 218 | // send_eap_frame 219 | // description: 220 | // 发送与之对应的 RESPONSE EAP frame (EAPOL-START frame 不算) 给服务器 221 | // 进行后续的认证 222 | //------------------------------------------------------------------------ 223 | int send_eap_frame(SEND_FRAME_TYPE type, const uint8_t *frame) 224 | { 225 | uint8_t *send_eap_frame_data; 226 | // const struct pcap_pkthdr* header; 227 | unsigned int send_eap_frame_data_length; 228 | // const struct ether_header *ethernet_header; 229 | // uint8_t *eap_md5_value_size = NULL; 230 | // uint8_t eap_request_md5_value[EAP_MD5_VALUE_LENGTH]; // 该hex数组从服务器发送的 request-md5-challenge frame 中提取 231 | // uint8_t eap_id = 0x01; // default 0x01, 详见 RFC 3748 232 | extern unsigned int midnight; 233 | 234 | switch(type) { 235 | case EAPOL_START: 236 | // ethernet_header = (struct ether_header*)(frame); // extract ethernet header values 237 | construct_eapol_start_frame(frame); 238 | send_eap_frame_data = eapol_start; 239 | send_eap_frame_data_length = 1000; 240 | 241 | fprintf(stdout, "sending eapol start frame\n"); 242 | break; 243 | 244 | case EAP_REQUEST_IDENTITY: 245 | // ethernet_header = (struct ether_header*)(frame); // extract ethernet header values 246 | 247 | // eap_id = frame[EAP_ID_ADDRESS]; 248 | construct_eap_response_identity_frame(frame); 249 | send_eap_frame_data = eap_response_identity; 250 | send_eap_frame_data_length = 1000; 251 | 252 | fprintf(stdout, "sending eap_response_identity frame\n"); 253 | break; 254 | 255 | case EAP_REQUEST_MD5_CHALLENGE: 256 | // ethernet_header = (struct ether_header*)(frame); // extract ethernet header values 257 | 258 | // copy eap md5 value from request md5-challenge-frame sent by server 259 | // strncpy(eap_request_md5_value, frame+24, EAP_MD5_VALUE_LENGTH); 260 | // eap_md5_value_size = (uint8_t*)malloc(1 * sizeof(uint8_t)); 261 | // memcpy(eap_md5_value_size, (frame + 0x17), 1); 262 | // construct_eap_response_md5_challenge_frame(ethernet_header->ether_shost, eap_request_md5_value, eap_md5_value_size, frame); 263 | construct_eap_response_md5_challenge_frame(frame); 264 | send_eap_frame_data = eap_response_md5_challenge; 265 | send_eap_frame_data_length = 1000; 266 | 267 | fprintf(stdout, "sending eap_md5_challenge frame\n"); 268 | break; 269 | 270 | case EAP_SUCCESS: 271 | // midnight_relogin() fucion not use anymore 272 | //if(midnight) 273 | // midnight_relogin(); 274 | 275 | // ethernet_header = (struct ether_header*)(frame); // extract ethernet header values 276 | // construct_eapol_heartbeat_frame(ethernet_header->ether_shost, frame); 277 | construct_eapol_heartbeat_frame(frame); 278 | send_eap_frame_data = eapol_heartbeat; 279 | send_eap_frame_data_length = 45; 280 | 281 | fprintf(stdout, "login success !\n"); 282 | break; 283 | 284 | case ONLINE: 285 | fillEchoPacket(eapol_heartbeat); 286 | send_eap_frame_data = eapol_heartbeat; 287 | send_eap_frame_data_length = 45; 288 | 289 | break; 290 | 291 | default: 292 | fprintf(stdout, "wrong send frame type.%02x\n", type); 293 | exit(EXIT_FAILURE); 294 | } 295 | 296 | // open a pcap packet capture descriptor for the specified interface. 297 | char pcap_errbuf[PCAP_ERRBUF_SIZE]; 298 | pcap_t* descr = pcap_open_live(nic_info.nic_name, SNAP_LENGTH, 1, 1000, pcap_errbuf); 299 | if(descr == NULL) { 300 | fprintf(stderr, "%s", pcap_errbuf); 301 | } 302 | if(!descr) { 303 | fprintf(stdout, "can't live ethernet interface\n"); 304 | 305 | return -1; 306 | } 307 | 308 | // write the ethernet frame to the interface. 309 | if(pcap_inject(descr, send_eap_frame_data, send_eap_frame_data_length) == -1) 310 | { 311 | fprintf(stderr, "error occur when seding %d frame: %s\n", type, pcap_geterr(descr)); 312 | pcap_perror(descr, 0); 313 | pcap_close(descr); 314 | // free(eap_md5_value_size); 315 | 316 | return -1; 317 | } 318 | 319 | // clean sent frames 320 | switch(type) { 321 | case EAPOL_START: 322 | memset(eapol_start, 0, sizeof(eapol_start)); 323 | break; 324 | 325 | case EAP_REQUEST_IDENTITY: 326 | memset(eap_response_identity, 0, sizeof(eap_response_identity)); 327 | break; 328 | 329 | case EAP_REQUEST_MD5_CHALLENGE: 330 | memset(eap_response_md5_challenge, 0, sizeof(eap_response_md5_challenge)); 331 | // free(eap_md5_value_size); 332 | break; 333 | 334 | case EAP_SUCCESS: 335 | break; 336 | 337 | case ONLINE: 338 | break; 339 | 340 | dafault: 341 | fprintf(stderr, "wrong frame type to be cleaned !\n"); 342 | exit(EXIT_FAILURE); 343 | } 344 | send_eap_frame_data = NULL; 345 | 346 | // close the pcap descriptor 347 | pcap_close(descr); 348 | 349 | return 0; 350 | } 351 | 352 | 353 | 354 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/mentohust_encryption/rjripemd128.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Copyright (C) 2009 Gabriel A. Petursson 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "ampheck.h" 24 | #include "rjripemd128.h" 25 | 26 | #define RIPEMD128_R1(x, y, z) ((x ^ y ^ z) + 2) 27 | #define RIPEMD128_R2(x, y, z) (((x & y) | (~x & z)) + 0x325b99a1) 28 | #define RIPEMD128_R3(x, y, z) (((x | ~y) ^ z) + 0x1baed69c) 29 | #define RIPEMD128_R4(x, y, z) (((x & z) | (y & ~z)) + 0xbcdcb1f9) 30 | #define RIPEMD128_R5(x, y, z) (((x & z) | (y & ~z)) + 0x5a82798a) 31 | #define RIPEMD128_R6(x, y, z) (((x | ~y) ^ z) + 0x41d42d5d) 32 | #define RIPEMD128_R7(x, y, z) (((x & y) | (~x & z)) + 0x30ed3f68) 33 | #define RIPEMD128_R8 RIPEMD128_R1 34 | 35 | #define RIPEMD128_PRC(a, b, c, d, idx, rot, rnd) { \ 36 | wv[a] = ROL(wv[a] + RIPEMD128_R##rnd(wv[b], wv[c], wv[d]) + idx, rot); \ 37 | } 38 | 39 | void ampheck_ripemd128_init(struct ampheck_ripemd128 *ctx) 40 | { 41 | ctx->h[0] = 0x10257436; 42 | ctx->h[1] = 0xa8bd9cfe; 43 | ctx->h[2] = 0x9efcad8b; 44 | ctx->h[3] = 0x12375460; 45 | 46 | ctx->length = 0; 47 | } 48 | 49 | void ampheck_ripemd128_transform(struct ampheck_ripemd128 *ctx, const uint8_t *data, size_t blocks) 50 | { 51 | size_t i; 52 | for (i = 0; i < blocks; ++i) { 53 | uint32_t wv[8]; 54 | uint32_t w[16]; 55 | 56 | PACK_32_LE(&data[(i << 6) ], &w[ 0]); 57 | PACK_32_LE(&data[(i << 6) + 4], &w[ 1]); 58 | PACK_32_LE(&data[(i << 6) + 8], &w[ 2]); 59 | PACK_32_LE(&data[(i << 6) + 12], &w[ 3]); 60 | PACK_32_LE(&data[(i << 6) + 16], &w[ 4]); 61 | PACK_32_LE(&data[(i << 6) + 20], &w[ 5]); 62 | PACK_32_LE(&data[(i << 6) + 24], &w[ 6]); 63 | PACK_32_LE(&data[(i << 6) + 28], &w[ 7]); 64 | PACK_32_LE(&data[(i << 6) + 32], &w[ 8]); 65 | PACK_32_LE(&data[(i << 6) + 36], &w[ 9]); 66 | PACK_32_LE(&data[(i << 6) + 40], &w[10]); 67 | PACK_32_LE(&data[(i << 6) + 44], &w[11]); 68 | PACK_32_LE(&data[(i << 6) + 48], &w[12]); 69 | PACK_32_LE(&data[(i << 6) + 52], &w[13]); 70 | PACK_32_LE(&data[(i << 6) + 56], &w[14]); 71 | PACK_32_LE(&data[(i << 6) + 60], &w[15]); 72 | 73 | wv[0] = ctx->h[0]; 74 | wv[1] = ctx->h[1]; 75 | wv[2] = ctx->h[2]; 76 | wv[3] = ctx->h[3]; 77 | memcpy(&wv[4], wv, 4 * sizeof(uint32_t)); 78 | 79 | RIPEMD128_PRC(0, 1, 2, 3, w[ 0], 11, 1); 80 | RIPEMD128_PRC(3, 0, 1, 2, w[ 1], 14, 1); 81 | RIPEMD128_PRC(2, 3, 0, 1, w[ 2], 15, 1); 82 | RIPEMD128_PRC(1, 2, 3, 0, w[ 3], 12, 1); 83 | RIPEMD128_PRC(0, 1, 2, 3, w[ 4], 5, 1); 84 | RIPEMD128_PRC(3, 0, 1, 2, w[ 5], 8, 1); 85 | RIPEMD128_PRC(2, 3, 0, 1, w[ 6], 7, 1); 86 | RIPEMD128_PRC(1, 2, 3, 0, w[ 7], 9, 1); 87 | RIPEMD128_PRC(0, 1, 2, 3, w[ 8], 11, 1); 88 | RIPEMD128_PRC(3, 0, 1, 2, w[ 9], 13, 1); 89 | RIPEMD128_PRC(2, 3, 0, 1, w[10], 14, 1); 90 | RIPEMD128_PRC(1, 2, 3, 0, w[11], 15, 1); 91 | RIPEMD128_PRC(0, 1, 2, 3, w[12], 6, 1); 92 | RIPEMD128_PRC(3, 0, 1, 2, w[13], 7, 1); 93 | RIPEMD128_PRC(2, 3, 0, 1, w[14], 9, 1); 94 | RIPEMD128_PRC(1, 2, 3, 0, w[15], 8, 1); 95 | 96 | RIPEMD128_PRC(0, 1, 2, 3, w[ 7], 7, 2); 97 | ///RIPEMD128_PRC(3, 0, 1, 2, w[ 4] + 2, 6, 2); 98 | wv[3] = ROL(wv[3]+ ((wv[0] & (wv[1]^wv[2]))^wv[2]) + w[4] + 2, 6); 99 | RIPEMD128_PRC(2, 3, 0, 1, w[13], 8, 2); 100 | RIPEMD128_PRC(1, 2, 3, 0, w[ 1], 13, 2); 101 | RIPEMD128_PRC(0, 1, 2, 3, w[10], 11, 2); 102 | RIPEMD128_PRC(3, 0, 1, 2, w[ 6], 9, 2); 103 | RIPEMD128_PRC(2, 3, 0, 1, w[15], 7, 2); 104 | ///RIPEMD128_PRC(1, 2, 3, 0, w[ 3], 15, 2); 105 | wv[1] = ROL(wv[1]+ ((wv[2] & (wv[3]^wv[0]))^wv[0]) + w[3] - 0x43234e07, 15); 106 | RIPEMD128_PRC(0, 1, 2, 3, w[12], 7, 2); 107 | ///RIPEMD128_PRC(3, 0, 1, 2, w[ 0] + 2, 12, 2); 108 | wv[3] = ROL(wv[3]+ ((wv[0] & (wv[1]^wv[2]))^wv[2]) + w[0] + 2, 12); 109 | RIPEMD128_PRC(2, 3, 0, 1, w[ 9], 15, 2); 110 | RIPEMD128_PRC(1, 2, 3, 0, w[ 5], 9, 2); 111 | RIPEMD128_PRC(0, 1, 2, 3, w[ 2], 11, 2); 112 | RIPEMD128_PRC(3, 0, 1, 2, w[14], 7, 2); 113 | RIPEMD128_PRC(2, 3, 0, 1, w[11], 13, 2); 114 | ///RIPEMD128_PRC(1, 2, 3, 0, w[ 8], 12, 2); 115 | wv[1] = ROL(wv[1]+ ((wv[2] & (wv[3]^wv[0]))^wv[0]) + w[8] + 2, 12); 116 | 117 | RIPEMD128_PRC(0, 1, 2, 3, w[ 3], 11, 3); 118 | RIPEMD128_PRC(3, 0, 1, 2, w[10], 13, 3); 119 | RIPEMD128_PRC(2, 3, 0, 1, w[14], 6, 3); 120 | RIPEMD128_PRC(1, 2, 3, 0, w[ 4], 7, 3); 121 | RIPEMD128_PRC(0, 1, 2, 3, w[ 9], 14, 3); 122 | RIPEMD128_PRC(3, 0, 1, 2, w[15], 9, 3); 123 | RIPEMD128_PRC(2, 3, 0, 1, w[ 8], 13, 3); 124 | RIPEMD128_PRC(1, 2, 3, 0, w[ 1], 15, 3); 125 | RIPEMD128_PRC(0, 1, 2, 3, w[ 2], 14, 3); 126 | RIPEMD128_PRC(3, 0, 1, 2, w[ 7], 8, 3); 127 | RIPEMD128_PRC(2, 3, 0, 1, w[ 0], 13, 3); 128 | ///RIPEMD128_PRC(1, 2, 3, 0, w[ 6], 6, 3); 129 | wv[1] = ROL(wv[1] + ((wv[2] | ~wv[3]) ^ wv[0]) +w[6] + 0x325b99a1, 6); 130 | RIPEMD128_PRC(0, 1, 2, 3, w[13], 5, 3); 131 | ///RIPEMD128_PRC(3, 0, 1, 2, w[11], 12, 3); 132 | wv[3] = ROL(wv[3] + ((wv[0] | ~wv[1]) ^ wv[2]) +w[11] - 0x43234e06, 12); 133 | RIPEMD128_PRC(2, 3, 0, 1, w[ 5], 7, 3); 134 | RIPEMD128_PRC(1, 2, 3, 0, w[12], 5, 3); 135 | 136 | RIPEMD128_PRC(0, 1, 2, 3, w[ 1], 11, 4); 137 | RIPEMD128_PRC(3, 0, 1, 2, w[ 9], 12, 4); 138 | ///RIPEMD128_PRC(2, 3, 0, 1, w[11], 14, 4); 139 | wv[2] = ROL(wv[2] + ((wv[3] & wv[1]) | (wv[0] & ~wv[1])) + w[11] + 0x325b99a1, 14); 140 | RIPEMD128_PRC(1, 2, 3, 0, w[10], 15, 4); 141 | RIPEMD128_PRC(0, 1, 2, 3, w[ 0], 14, 4); 142 | RIPEMD128_PRC(3, 0, 1, 2, w[ 8] + 2, 15, 4); 143 | RIPEMD128_PRC(2, 3, 0, 1, w[12], 9, 4); 144 | RIPEMD128_PRC(1, 2, 3, 0, w[ 4], 8, 4); 145 | RIPEMD128_PRC(0, 1, 2, 3, w[13], 9, 4); 146 | ///RIPEMD128_PRC(3, 0, 1, 2, w[ 3], 14, 4); 147 | wv[3] = ROL(wv[3] + ((wv[0] & wv[2]) | (wv[1] & ~wv[2])) + w[3] + 0x1baed69c, 14); 148 | RIPEMD128_PRC(2, 3, 0, 1, w[ 7], 5, 4); 149 | ///RIPEMD128_PRC(1, 2, 3, 0, w[15], 6, 4); 150 | wv[1] = ROL(wv[1] + ((wv[2] & wv[0]) | (wv[3] & ~wv[0])) + w[15] + 2, 6); 151 | RIPEMD128_PRC(0, 1, 2, 3, w[14], 8, 4); 152 | RIPEMD128_PRC(3, 0, 1, 2, w[ 5], 6, 4); 153 | RIPEMD128_PRC(2, 3, 0, 1, w[ 6], 5, 4); 154 | ///RIPEMD128_PRC(1, 2, 3, 0, w[ 2], 12, 4); 155 | wv[1] = ROL(wv[1] + ((wv[2] & wv[0]) | (wv[3] & ~wv[0])) + w[ 2] - 0x43234e04, 12); 156 | 157 | RIPEMD128_PRC(4, 5, 6, 7, w[ 5], 8, 5); 158 | RIPEMD128_PRC(7, 4, 5, 6, w[14], 9, 5); 159 | RIPEMD128_PRC(6, 7, 4, 5, w[ 7], 9, 5); 160 | RIPEMD128_PRC(5, 6, 7, 4, w[ 0], 11, 5); 161 | RIPEMD128_PRC(4, 5, 6, 7, w[ 9], 13, 5); 162 | RIPEMD128_PRC(7, 4, 5, 6, w[ 2], 15, 5); 163 | ///RIPEMD128_PRC(6, 7, 4, 5, w[11], 15, 5); 164 | wv[6] = ROL(wv[6] + ((wv[7] & wv[5]) | (wv[4] & ~wv[5])) + w[11] + 0x325b99a1, 15); 165 | RIPEMD128_PRC(5, 6, 7, 4, w[ 4], 5, 5); 166 | RIPEMD128_PRC(4, 5, 6, 7, w[13], 7, 5); 167 | RIPEMD128_PRC(7, 4, 5, 6, w[ 6], 7, 5); 168 | ///RIPEMD128_PRC(6, 7, 4, 5, w[15], 8, 5); 169 | wv[6] = ROL(wv[6] + ((wv[7] & wv[5]) | (wv[4] & ~wv[5])) + w[15] - 0x43234e07, 8); 170 | RIPEMD128_PRC(5, 6, 7, 4, w[ 8], 11, 5); 171 | RIPEMD128_PRC(4, 5, 6, 7, w[ 1], 14, 5); 172 | RIPEMD128_PRC(7, 4, 5, 6, w[10], 14, 5); 173 | ///RIPEMD128_PRC(6, 7, 4, 5, w[ 3], 12, 5); 174 | wv[6] = ROL(wv[6] + ((wv[7] & wv[5]) | (wv[4] & ~wv[5])) + w[3] - 0x43234e04, 12); 175 | RIPEMD128_PRC(5, 6, 7, 4, w[12], 6, 5); 176 | 177 | RIPEMD128_PRC(4, 5, 6, 7, w[ 6], 9, 6); 178 | RIPEMD128_PRC(7, 4, 5, 6, w[11], 13, 6); 179 | RIPEMD128_PRC(6, 7, 4, 5, w[ 3], 15, 6); 180 | RIPEMD128_PRC(5, 6, 7, 4, w[ 7], 7, 6); 181 | RIPEMD128_PRC(4, 5, 6, 7, w[ 0], 12, 6); 182 | RIPEMD128_PRC(7, 4, 5, 6, w[13], 8, 6); 183 | ///RIPEMD128_PRC(6, 7, 4, 5, w[ 5], 9, 6); 184 | wv[6] = ROL(wv[6] + ((wv[7] | ~wv[4]) ^ wv[5]) +w[5] - 0x43234e07, 9); 185 | ///RIPEMD128_PRC(5, 6, 7, 4, w[10], 11, 6); 186 | wv[5] = ROL(wv[5] + ((wv[6] | ~wv[7]) ^ wv[4]) +w[10] - 0x43234e03, 11); 187 | RIPEMD128_PRC(4, 5, 6, 7, w[14], 7, 6); 188 | RIPEMD128_PRC(7, 4, 5, 6, w[15], 7, 6); 189 | RIPEMD128_PRC(6, 7, 4, 5, w[ 8], 12, 6); 190 | RIPEMD128_PRC(5, 6, 7, 4, w[12], 7, 6); 191 | RIPEMD128_PRC(4, 5, 6, 7, w[ 4], 6, 6); 192 | RIPEMD128_PRC(7, 4, 5, 6, w[ 9], 15, 6); 193 | ///RIPEMD128_PRC(6, 7, 4, 5, w[ 1], 13, 6); 194 | wv[6] = ROL(wv[6] + ((wv[7] | ~wv[4]) ^ wv[5]) + w[1] + 0x325b99a1, 13); 195 | RIPEMD128_PRC(5, 6, 7, 4, w[ 2], 11, 6); 196 | 197 | RIPEMD128_PRC(4, 5, 6, 7, w[15], 9, 7); 198 | RIPEMD128_PRC(7, 4, 5, 6, w[ 5], 7, 7); 199 | RIPEMD128_PRC(6, 7, 4, 5, w[ 1], 15, 7); 200 | RIPEMD128_PRC(5, 6, 7, 4, w[ 3], 11, 7); 201 | RIPEMD128_PRC(4, 5, 6, 7, w[ 7], 8, 7); 202 | RIPEMD128_PRC(7, 4, 5, 6, w[14], 6, 7); 203 | ///RIPEMD128_PRC(6, 7, 4, 5, w[ 6], 6, 7); 204 | wv[6] = ROL(wv[6] + ((wv[7] & wv[4]) | (~wv[7] & wv[5])) + w[6] - 0x43234e02, 6); 205 | RIPEMD128_PRC(5, 6, 7, 4, w[ 9], 14, 7); 206 | RIPEMD128_PRC(4, 5, 6, 7, w[11], 12, 7); 207 | ///RIPEMD128_PRC(7, 4, 5, 6, w[ 8], 13, 7); 208 | wv[7] = ROL(wv[7] + ((wv[4] & wv[5]) | (~wv[4] & wv[6])) + w[8] + 0x5a82798a, 13); 209 | RIPEMD128_PRC(6, 7, 4, 5, w[12], 5, 7); 210 | RIPEMD128_PRC(5, 6, 7, 4, w[ 2], 14, 7); 211 | RIPEMD128_PRC(4, 5, 6, 7, w[10], 13, 7); 212 | RIPEMD128_PRC(7, 4, 5, 6, w[ 0], 13, 7); 213 | ///RIPEMD128_PRC(6, 7, 4, 5, w[ 4], 7, 7); 214 | wv[6] = ROL(wv[6] + ((wv[7] & wv[4]) | (~wv[7] & wv[5])) + w[4] + 0x41d42d5d, 7); 215 | RIPEMD128_PRC(5, 6, 7, 4, w[13], 5, 7); 216 | 217 | RIPEMD128_PRC(4, 5, 6, 7, w[ 8], 15, 8); 218 | ///RIPEMD128_PRC(7, 4, 5, 6, w[ 6], 5, 8); 219 | wv[7] = ROL(wv[7] + (wv[4] ^ wv[5] ^ wv[6]) + w[6] - 0x43234e02, 5); 220 | RIPEMD128_PRC(6, 7, 4, 5, w[ 4], 8, 8); 221 | RIPEMD128_PRC(5, 6, 7, 4, w[ 1], 11, 8); 222 | RIPEMD128_PRC(4, 5, 6, 7, w[ 3], 14, 8); 223 | RIPEMD128_PRC(7, 4, 5, 6, w[11], 14, 8); 224 | RIPEMD128_PRC(6, 7, 4, 5, w[15], 6, 8); 225 | RIPEMD128_PRC(5, 6, 7, 4, w[ 0], 14, 8); 226 | RIPEMD128_PRC(4, 5, 6, 7, w[ 5], 6, 8); 227 | RIPEMD128_PRC(7, 4, 5, 6, w[12], 9, 8); 228 | RIPEMD128_PRC(6, 7, 4, 5, w[ 2], 12, 8); 229 | RIPEMD128_PRC(5, 6, 7, 4, w[13], 9, 8); 230 | RIPEMD128_PRC(4, 5, 6, 7, w[ 9], 12, 8); 231 | RIPEMD128_PRC(7, 4, 5, 6, w[ 7], 5, 8); 232 | RIPEMD128_PRC(6, 7, 4, 5, w[10], 15, 8); 233 | RIPEMD128_PRC(5, 6, 7, 4, w[14], 8, 8); 234 | 235 | wv[7] += wv[2] + ctx->h[1]; 236 | ctx->h[1] = ctx->h[2] + wv[3] + wv[4]; 237 | ctx->h[2] = ctx->h[3] + wv[0] + wv[5] + 1; 238 | ctx->h[3] = ctx->h[0] + wv[1] + wv[6]; 239 | ctx->h[0] = wv[7]; 240 | } 241 | } 242 | 243 | void ampheck_ripemd128_update(struct ampheck_ripemd128 *ctx, const uint8_t *data, size_t size) 244 | { 245 | size_t tmp = size; 246 | 247 | if (size >= 64 - ctx->length % 64) { 248 | memcpy(&ctx->buffer[ctx->length % 64], data, 64 - ctx->length % 64); 249 | 250 | data += 64 - ctx->length % 64; 251 | size -= 64 - ctx->length % 64; 252 | 253 | ampheck_ripemd128_transform(ctx, ctx->buffer, 1); 254 | ampheck_ripemd128_transform(ctx, data, size / 64); 255 | 256 | data += size & ~63; 257 | size %= 64; 258 | 259 | memcpy(ctx->buffer, data, size); 260 | } else { 261 | memcpy(&ctx->buffer[ctx->length % 64], data, size); 262 | } 263 | 264 | ctx->length += tmp; 265 | } 266 | 267 | void ampheck_ripemd128_finish(const struct ampheck_ripemd128 *ctx, uint8_t *digest) 268 | { 269 | struct ampheck_ripemd128 tmp; 270 | 271 | memcpy(tmp.h, ctx->h, 4 * sizeof(uint32_t)); 272 | memcpy(tmp.buffer, ctx->buffer, ctx->length % 64); 273 | 274 | tmp.buffer[ctx->length % 64] = 0x80; 275 | 276 | if (ctx->length % 64 < 56) { 277 | memset(&tmp.buffer[ctx->length % 64 + 1], 0x00, 55 - ctx->length % 64); 278 | } else { 279 | memset(&tmp.buffer[ctx->length % 64 + 1], 0x00, 63 - ctx->length % 64); 280 | ampheck_ripemd128_transform(&tmp, tmp.buffer, 1); 281 | 282 | memset(tmp.buffer, 0x00, 56); 283 | } 284 | 285 | UNPACK_64_LE(ctx->length * 8, &tmp.buffer[56]); 286 | ampheck_ripemd128_transform(&tmp, tmp.buffer, 1); 287 | 288 | UNPACK_32_LE(tmp.h[0], &digest[ 0]); 289 | UNPACK_32_LE(tmp.h[1], &digest[ 4]); 290 | UNPACK_32_LE(tmp.h[2], &digest[ 8]); 291 | UNPACK_32_LE(tmp.h[3], &digest[12]); 292 | } 293 | -------------------------------------------------------------------------------- /src/mentohust_encryption/md5.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | L. Peter Deutsch 21 | ghost@aladdin.com 22 | 23 | */ 24 | /* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ 25 | /* 26 | Independent implementation of MD5 (RFC 1321). 27 | 28 | This code implements the MD5 Algorithm defined in RFC 1321, whose 29 | text is available at 30 | http://www.ietf.org/rfc/rfc1321.txt 31 | The code is derived from the text of the RFC, including the test suite 32 | (section A.5) but excluding the rest of Appendix A. It does not include 33 | any code or documentation that is identified in the RFC as being 34 | copyrighted. 35 | 36 | The original and principal author of md5.c is L. Peter Deutsch 37 | . Other authors are noted in the change history 38 | that follows (in reverse chronological order): 39 | 40 | 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order 41 | either statically or dynamically; added missing #include 42 | in library. 43 | 2002-03-11 lpd Corrected argument list for main(), and added int return 44 | type, in test program and T value program. 45 | 2002-02-21 lpd Added missing #include in test program. 46 | 2000-07-03 lpd Patched to eliminate warnings about "constant is 47 | unsigned in ANSI C, signed in traditional"; made test program 48 | self-checking. 49 | 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 50 | 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 51 | 1999-05-03 lpd Original version. 52 | */ 53 | 54 | #include "md5.h" 55 | #include 56 | 57 | #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ 58 | #ifdef ARCH_IS_BIG_ENDIAN 59 | # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) 60 | #else 61 | # define BYTE_ORDER 0 62 | #endif 63 | 64 | #define T_MASK ((md5_word_t)~0) 65 | #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) 66 | #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) 67 | #define T3 0x242070db 68 | #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) 69 | #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) 70 | #define T6 0x4787c62a 71 | #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) 72 | #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) 73 | #define T9 0x698098d8 74 | #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) 75 | #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) 76 | #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) 77 | #define T13 0x6b901122 78 | #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) 79 | #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) 80 | #define T16 0x49b40821 81 | #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) 82 | #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) 83 | #define T19 0x265e5a51 84 | #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) 85 | #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) 86 | #define T22 0x02441453 87 | #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) 88 | #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) 89 | #define T25 0x21e1cde6 90 | #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) 91 | #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) 92 | #define T28 0x455a14ed 93 | #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) 94 | #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) 95 | #define T31 0x676f02d9 96 | #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) 97 | #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) 98 | #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) 99 | #define T35 0x6d9d6122 100 | #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) 101 | #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) 102 | #define T38 0x4bdecfa9 103 | #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) 104 | #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) 105 | #define T41 0x289b7ec6 106 | #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) 107 | #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) 108 | #define T44 0x04881d05 109 | #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) 110 | #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) 111 | #define T47 0x1fa27cf8 112 | #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) 113 | #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) 114 | #define T50 0x432aff97 115 | #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) 116 | #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) 117 | #define T53 0x655b59c3 118 | #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) 119 | #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) 120 | #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) 121 | #define T57 0x6fa87e4f 122 | #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) 123 | #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) 124 | #define T60 0x4e0811a1 125 | #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) 126 | #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) 127 | #define T63 0x2ad7d2bb 128 | #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) 129 | 130 | 131 | static void 132 | md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) 133 | { 134 | md5_word_t 135 | a = pms->abcd[0], b = pms->abcd[1], 136 | c = pms->abcd[2], d = pms->abcd[3]; 137 | md5_word_t t; 138 | #if BYTE_ORDER > 0 139 | /* Define storage only for big-endian CPUs. */ 140 | md5_word_t X[16]; 141 | #else 142 | /* Define storage for little-endian or both types of CPUs. */ 143 | md5_word_t xbuf[16]; 144 | const md5_word_t *X; 145 | #endif 146 | 147 | { 148 | #if BYTE_ORDER == 0 149 | /* 150 | * Determine dynamically whether this is a big-endian or 151 | * little-endian machine, since we can use a more efficient 152 | * algorithm on the latter. 153 | */ 154 | static const int w = 1; 155 | 156 | if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ 157 | #endif 158 | #if BYTE_ORDER <= 0 /* little-endian */ 159 | { 160 | /* 161 | * On little-endian machines, we can process properly aligned 162 | * data without copying it. 163 | */ 164 | if (!((data - (const md5_byte_t *)0) & 3)) { 165 | /* data are properly aligned */ 166 | X = (const md5_word_t *)data; 167 | } else { 168 | /* not aligned */ 169 | memcpy(xbuf, data, 64); 170 | X = xbuf; 171 | } 172 | } 173 | #endif 174 | #if BYTE_ORDER == 0 175 | else /* dynamic big-endian */ 176 | #endif 177 | #if BYTE_ORDER >= 0 /* big-endian */ 178 | { 179 | /* 180 | * On big-endian machines, we must arrange the bytes in the 181 | * right order. 182 | */ 183 | const md5_byte_t *xp = data; 184 | int i; 185 | 186 | # if BYTE_ORDER == 0 187 | X = xbuf; /* (dynamic only) */ 188 | # else 189 | # define xbuf X /* (static only) */ 190 | # endif 191 | for (i = 0; i < 16; ++i, xp += 4) 192 | xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); 193 | } 194 | #endif 195 | } 196 | 197 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) 198 | 199 | /* Round 1. */ 200 | /* Let [abcd k s i] denote the operation 201 | a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ 202 | #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) 203 | #define SET(a, b, c, d, k, s, Ti)\ 204 | t = a + F(b,c,d) + X[k] + Ti;\ 205 | a = ROTATE_LEFT(t, s) + b 206 | /* Do the following 16 operations. */ 207 | SET(a, b, c, d, 0, 7, T1); 208 | SET(d, a, b, c, 1, 12, T2); 209 | SET(c, d, a, b, 2, 17, T3); 210 | SET(b, c, d, a, 3, 22, T4); 211 | SET(a, b, c, d, 4, 7, T5); 212 | SET(d, a, b, c, 5, 12, T6); 213 | SET(c, d, a, b, 6, 17, T7); 214 | SET(b, c, d, a, 7, 22, T8); 215 | SET(a, b, c, d, 8, 7, T9); 216 | SET(d, a, b, c, 9, 12, T10); 217 | SET(c, d, a, b, 10, 17, T11); 218 | SET(b, c, d, a, 11, 22, T12); 219 | SET(a, b, c, d, 12, 7, T13); 220 | SET(d, a, b, c, 13, 12, T14); 221 | SET(c, d, a, b, 14, 17, T15); 222 | SET(b, c, d, a, 15, 22, T16); 223 | #undef SET 224 | 225 | /* Round 2. */ 226 | /* Let [abcd k s i] denote the operation 227 | a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ 228 | #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) 229 | #define SET(a, b, c, d, k, s, Ti)\ 230 | t = a + G(b,c,d) + X[k] + Ti;\ 231 | a = ROTATE_LEFT(t, s) + b 232 | /* Do the following 16 operations. */ 233 | SET(a, b, c, d, 1, 5, T17); 234 | SET(d, a, b, c, 6, 9, T18); 235 | SET(c, d, a, b, 11, 14, T19); 236 | SET(b, c, d, a, 0, 20, T20); 237 | SET(a, b, c, d, 5, 5, T21); 238 | SET(d, a, b, c, 10, 9, T22); 239 | SET(c, d, a, b, 15, 14, T23); 240 | SET(b, c, d, a, 4, 20, T24); 241 | SET(a, b, c, d, 9, 5, T25); 242 | SET(d, a, b, c, 14, 9, T26); 243 | SET(c, d, a, b, 3, 14, T27); 244 | SET(b, c, d, a, 8, 20, T28); 245 | SET(a, b, c, d, 13, 5, T29); 246 | SET(d, a, b, c, 2, 9, T30); 247 | SET(c, d, a, b, 7, 14, T31); 248 | SET(b, c, d, a, 12, 20, T32); 249 | #undef SET 250 | 251 | /* Round 3. */ 252 | /* Let [abcd k s t] denote the operation 253 | a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ 254 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 255 | #define SET(a, b, c, d, k, s, Ti)\ 256 | t = a + H(b,c,d) + X[k] + Ti;\ 257 | a = ROTATE_LEFT(t, s) + b 258 | /* Do the following 16 operations. */ 259 | SET(a, b, c, d, 5, 4, T33); 260 | SET(d, a, b, c, 8, 11, T34); 261 | SET(c, d, a, b, 11, 16, T35); 262 | SET(b, c, d, a, 14, 23, T36); 263 | SET(a, b, c, d, 1, 4, T37); 264 | SET(d, a, b, c, 4, 11, T38); 265 | SET(c, d, a, b, 7, 16, T39); 266 | SET(b, c, d, a, 10, 23, T40); 267 | SET(a, b, c, d, 13, 4, T41); 268 | SET(d, a, b, c, 0, 11, T42); 269 | SET(c, d, a, b, 3, 16, T43); 270 | SET(b, c, d, a, 6, 23, T44); 271 | SET(a, b, c, d, 9, 4, T45); 272 | SET(d, a, b, c, 12, 11, T46); 273 | SET(c, d, a, b, 15, 16, T47); 274 | SET(b, c, d, a, 2, 23, T48); 275 | #undef SET 276 | 277 | /* Round 4. */ 278 | /* Let [abcd k s t] denote the operation 279 | a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ 280 | #define I(x, y, z) ((y) ^ ((x) | ~(z))) 281 | #define SET(a, b, c, d, k, s, Ti)\ 282 | t = a + I(b,c,d) + X[k] + Ti;\ 283 | a = ROTATE_LEFT(t, s) + b 284 | /* Do the following 16 operations. */ 285 | SET(a, b, c, d, 0, 6, T49); 286 | SET(d, a, b, c, 7, 10, T50); 287 | SET(c, d, a, b, 14, 15, T51); 288 | SET(b, c, d, a, 5, 21, T52); 289 | SET(a, b, c, d, 12, 6, T53); 290 | SET(d, a, b, c, 3, 10, T54); 291 | SET(c, d, a, b, 10, 15, T55); 292 | SET(b, c, d, a, 1, 21, T56); 293 | SET(a, b, c, d, 8, 6, T57); 294 | SET(d, a, b, c, 15, 10, T58); 295 | SET(c, d, a, b, 6, 15, T59); 296 | SET(b, c, d, a, 13, 21, T60); 297 | SET(a, b, c, d, 4, 6, T61); 298 | SET(d, a, b, c, 11, 10, T62); 299 | SET(c, d, a, b, 2, 15, T63); 300 | SET(b, c, d, a, 9, 21, T64); 301 | #undef SET 302 | 303 | /* Then perform the following additions. (That is increment each 304 | of the four registers by the value it had before this block 305 | was started.) */ 306 | pms->abcd[0] += a; 307 | pms->abcd[1] += b; 308 | pms->abcd[2] += c; 309 | pms->abcd[3] += d; 310 | } 311 | 312 | void 313 | md5_init(md5_state_t *pms) 314 | { 315 | pms->count[0] = pms->count[1] = 0; 316 | pms->abcd[0] = 0x67452301; 317 | pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; 318 | pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; 319 | pms->abcd[3] = 0x10325476; 320 | } 321 | 322 | void 323 | md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) 324 | { 325 | const md5_byte_t *p = data; 326 | int left = nbytes; 327 | int offset = (pms->count[0] >> 3) & 63; 328 | md5_word_t nbits = (md5_word_t)(nbytes << 3); 329 | 330 | if (nbytes <= 0) 331 | return; 332 | 333 | /* Update the message length. */ 334 | pms->count[1] += nbytes >> 29; 335 | pms->count[0] += nbits; 336 | if (pms->count[0] < nbits) 337 | pms->count[1]++; 338 | 339 | /* Process an initial partial block. */ 340 | if (offset) { 341 | int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); 342 | 343 | memcpy(pms->buf + offset, p, copy); 344 | if (offset + copy < 64) 345 | return; 346 | p += copy; 347 | left -= copy; 348 | md5_process(pms, pms->buf); 349 | } 350 | 351 | /* Process full blocks. */ 352 | for (; left >= 64; p += 64, left -= 64) 353 | md5_process(pms, p); 354 | 355 | /* Process a final partial block. */ 356 | if (left) 357 | memcpy(pms->buf, p, left); 358 | } 359 | 360 | void 361 | md5_finish(md5_state_t *pms, md5_byte_t digest[16]) 362 | { 363 | static const md5_byte_t pad[64] = { 364 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 365 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 366 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 367 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 368 | }; 369 | md5_byte_t data[8]; 370 | int i; 371 | 372 | /* Save the length before padding. */ 373 | for (i = 0; i < 8; ++i) 374 | data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); 375 | /* Pad to 56 bytes mod 64. */ 376 | md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); 377 | /* Append the length. */ 378 | md5_append(pms, data, 8); 379 | for (i = 0; i < 16; ++i) 380 | digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); 381 | } 382 | -------------------------------------------------------------------------------- /src/functions.c: -------------------------------------------------------------------------------- 1 | // 2 | //========================================================================= 3 | // 4 | // Filename: functions.c 5 | // 6 | // Description: 7 | // 8 | // Version: 1.0 9 | // Created: 04/29/2018 09:14:30 P.M. 10 | // Revision: none 11 | // Compiler: gcc 12 | // 13 | // Author: codingstory, codingstory.tw@gmail.com 14 | // 15 | // 1、从网络设备捕获 EAP frame 16 | // 2、判断捕获的 Request EAP frame type。 17 | // 3、发送与之对应的 EAP RESPONSE frame 给服务器进行后续的认证。 18 | // 19 | // 20 | //========================================================================= 21 | // 22 | 23 | #include "functions.h" 24 | 25 | static char* get_md5_digest(const char *str, size_t length) 26 | { 27 | static md5_byte_t digest[16]; 28 | 29 | md5_state_t state; 30 | md5_init(&state); 31 | md5_init(&state); 32 | md5_append(&state, (const md5_byte_t *)str, length); 33 | md5_finish(&state, digest); 34 | 35 | return (char*)digest; 36 | } 37 | 38 | uint8_t 39 | *calculate_the_eap_md5_value_in_response_md5_challenge_frame( 40 | const uint8_t id, const uint8_t *eap_request_md5_chag_value, unsigned int eap_md5_value_size) 41 | { 42 | extern char *password; 43 | extern unsigned int password_length; 44 | uint8_t *uint8_type_calculation_result; 45 | char *md5_algo_input_array, *calculation_result; 46 | unsigned int i = 0; 47 | unsigned int md5_algo_input_array_length = sizeof(id) + password_length + eap_md5_value_size; 48 | 49 | md5_algo_input_array = (char *)malloc(md5_algo_input_array_length * sizeof(char)); 50 | calculation_result = (char*)malloc(eap_md5_value_size * sizeof(char)); 51 | uint8_type_calculation_result = (uint8_t *)malloc( 52 | eap_md5_value_size * sizeof(uint8_t)); 53 | memset(md5_algo_input_array, 0, md5_algo_input_array_length); 54 | memset(calculation_result, 0, eap_md5_value_size); 55 | memset(uint8_type_calculation_result, 0, eap_md5_value_size); 56 | 57 | memcpy(md5_algo_input_array, &id, sizeof(id)); // cp id to input array 58 | memcpy((md5_algo_input_array + sizeof(id)), password, password_length); // cp password to input array 59 | memcpy(md5_algo_input_array + sizeof(id) + password_length, 60 | eap_request_md5_chag_value, eap_md5_value_size); // cp eap_request_md5_chag_value to input array 61 | 62 | // use the funciton get_md5_digest to calculate the EAP-MD5 Value in eap_response_md5_chag frame 63 | memcpy(calculation_result, get_md5_digest(md5_algo_input_array, 64 | md5_algo_input_array_length), eap_md5_value_size); 65 | 66 | // transfer the char* type result to uint8_t* type 67 | memcpy(uint8_type_calculation_result, calculation_result, eap_md5_value_size); 68 | 69 | #if defined(DEBUG) 70 | fprintf(stdout, "md5 result == "); 71 | for(i = 0; i < eap_md5_value_size; i++) { 72 | fprintf(stdout, "%02X ", uint8_type_calculation_result[i]); 73 | 74 | } 75 | #endif 76 | 77 | free(md5_algo_input_array); 78 | free(calculation_result); 79 | 80 | return uint8_type_calculation_result; 81 | } 82 | 83 | 84 | 85 | //------function---------------------------------------------------------- 86 | // name: 87 | // code_convert 88 | // description: 89 | // 字符串编码转换 90 | //------------------------------------------------------------------------ 91 | int code_convert(char *from_charset, char *to_charset, 92 | char *inbuf, size_t inlen, char *outbuf, size_t outlen) 93 | { 94 | iconv_t cd; 95 | // 此处错误处理很重要, 否则交叉编译到路由器运行出现Bus error 96 | if((cd = iconv_open(to_charset,from_charset)) == (iconv_t)-1) 97 | return -1; 98 | 99 | if (cd==0) 100 | return -1; 101 | memset(outbuf,0,outlen); 102 | 103 | if (iconv (cd, &inbuf, &inlen, &outbuf, &outlen) == (size_t)-1) 104 | return -1; 105 | iconv_close(cd); 106 | return 0; 107 | } 108 | 109 | void print_notification_msg(const uint8_t *frame) 110 | { 111 | char msg_buf[1024]; 112 | size_t msg_length; 113 | char *msg; 114 | 115 | // 锐捷的通知报文 116 | msg = (char*)(frame + 0x1b); 117 | msg_length = strlen (msg); 118 | code_convert ("gb2312", "utf-8", 119 | msg, msg_length, 120 | msg_buf, 1024); 121 | 122 | fprintf (stdout, ">>Ruijie 通知: %s\n", msg_buf); 123 | } 124 | 125 | void print_server_info(const uint8_t *frame) 126 | { 127 | char msg_buf[1024]; 128 | char *msg; 129 | uint16_t msg_length; 130 | uint16_t empty_length; 131 | uint16_t account_info_offset; 132 | 133 | msg_length = ntohs(*(uint16_t*)(frame + 0x1a)); 134 | empty_length = ntohs(*(uint16_t*)(frame + 0x1c + msg_length + 0x04)); 135 | account_info_offset = 0x1c + msg_length + 0x06 + empty_length + 0x12 + 0x09; 136 | 137 | // success和failure报文系统信息的固定位置 138 | if (msg_length) { 139 | msg = (char*)(frame + 0x1c); 140 | code_convert ("gb2312", "utf-8", 141 | msg, msg_length, 142 | msg_buf, 1024); 143 | if(strlen(msg_buf) > 0) 144 | fprintf (stdout, ">>Ruijie 通知: %s\n", msg_buf); 145 | } 146 | 147 | // success报文关于用户账户信息 148 | msg_length = *(uint8_t*)(frame + account_info_offset + 0x07); 149 | if (msg_length) { 150 | msg = (char*)(frame + account_info_offset + 0x08); 151 | code_convert ("gb2312", "utf-8", 152 | msg, msg_length, 153 | msg_buf, 1024); 154 | if(strlen(msg_buf) > 0) 155 | fprintf (stdout, ">>账户信息: %s\n", msg_buf); 156 | } 157 | 158 | return; 159 | } 160 | 161 | //------function---------------------------------------------------------- 162 | // name: 163 | // midnight_relogin 164 | // description: 165 | // midnight 模式, 重新认证以保证稳定不掉线。 166 | // 将 jmuSupplicant 各项 variables 恢复到初始状态, 以免存在 167 | // 脏数据影响认证 168 | //------------------------------------------------------------------------ 169 | int midnight_relogin() 170 | { 171 | extern unsigned int midnight; 172 | extern char *user_input_ipaddr; 173 | extern char *user_input_mask; 174 | extern char *service_company; 175 | extern NIC_STRUCT nic_info; 176 | extern unsigned int midnight_mode_change_tail_data; 177 | extern unsigned int midnight; 178 | extern SEND_FRAME_TYPE current_state; 179 | 180 | // midnight模式只需重认证一次, 此时正在准备重新认证, 181 | // 这次成功后就不许要再次重认证了 182 | midnight = 0; 183 | // 重认证时, start frame 和 response-md5-challenge frame 末端数据与 184 | // 普通认证时发送的不同。此处告知 construct_eap_frames.c 构造认证数 185 | // 据包时需要做对应的变动 186 | midnight_mode_change_tail_data = 1; 187 | user_input_ipaddr = NULL; // clean user_input_ipaddr, to get the network card real ip addr 188 | user_input_mask = NULL; 189 | service_company = NULL; 190 | // 重认证时服务名不能用'教育网接入',必须选择 '联通','电信'或'移动' 191 | // 这里写死,选联通 192 | service_company = (char*)calloc(1, sizeof(2)); 193 | strcpy(service_company, "1"); 194 | 195 | // 重新初始化认证参数 196 | init_login_config(); 197 | alarm(0); 198 | 199 | if(init_NIC_address(&nic_info) == -1) { // get network interface card MAC, ip, mask 200 | int errnum = errno; 201 | fprintf(stderr, "Value of errno: %d\n", errnum); 202 | perror("Error printed by perror"); 203 | fprintf(stderr, "Error get nic address: %s\n", strerror( errnum )); 204 | 205 | exit(1); 206 | } 207 | 208 | // 认证失败后服务器会立刻向 supplicant 发送几次 request-identity frame 209 | // 等待并忽略掉这些 frame, 然后重新'干净'地认证 210 | sleep(5); 211 | 212 | alarm(10); 213 | 214 | current_state = EAPOL_START; 215 | 216 | // 发送 EAPOL-START frame, 重启认证 217 | send_eap_frame(EAPOL_START, NULL); 218 | 219 | return 0; 220 | } 221 | 222 | 223 | //------function---------------------------------------------------------- 224 | // name: 225 | // relogin_when_receive_failure_frame 226 | // description: 227 | // 认证时失败, 自动重启认证 228 | // 将 jmuSupplicant 各项 variables 恢复到初始状态, 以免存在 229 | // 脏数据影响认证 230 | //------------------------------------------------------------------------ 231 | int relogin_when_receive_failure_frame() 232 | { 233 | extern char *user_input_ipaddr; 234 | extern char *user_input_mask; 235 | extern char *user_input_ipaddr_bp; 236 | extern char *user_input_mask_bp; 237 | extern char *service_company; 238 | extern char *service_company_bp; 239 | extern unsigned int midnight; 240 | extern unsigned int midnight_bp; 241 | extern NIC_STRUCT nic_info; 242 | extern SEND_FRAME_TYPE current_state; 243 | 244 | static unsigned int relogin_number = 0; // 重认证次数,超过5次停止重认证 245 | 246 | 247 | if(relogin_number > 5) 248 | { 249 | fprintf(stdout, "\n\nregloin over 5 times, please check your username, password or service name\n\n"); 250 | exit(1); 251 | } 252 | fprintf(stdout, "\n\nThe program is running relogin function.\n\n\n"); 253 | if(user_input_ipaddr_bp != NULL) 254 | { 255 | // 用户输入的 ipaddr, 保存在 char **argv 数组中。无法 free() 256 | // 第二次至第五次重认证时, ipaddr 保存在 jmuSupplicant malloc() 257 | // 出来的内存中,因此可以正常 free() 258 | if(relogin_number) 259 | free(user_input_ipaddr); 260 | user_input_ipaddr = user_input_ipaddr_bp; 261 | user_input_ipaddr_bp = NULL; 262 | } 263 | if(user_input_mask_bp != NULL) 264 | { 265 | if(relogin_number) 266 | free(user_input_mask); 267 | user_input_mask = user_input_mask_bp; 268 | user_input_mask_bp = NULL; 269 | } 270 | if(midnight_bp) 271 | { 272 | midnight = midnight_bp; 273 | midnight_bp = 0; 274 | } 275 | if(service_company_bp != NULL) 276 | { 277 | if(relogin_number) 278 | free(service_company); 279 | service_company = service_company_bp; 280 | service_company = NULL; 281 | } 282 | relogin_number++; 283 | 284 | init_login_config(); 285 | alarm(0); 286 | 287 | if(init_NIC_address(&nic_info) == -1) { // get network interface card MAC, ip, mask 288 | int errnum = errno; 289 | fprintf(stderr, "Value of errno: %d\n", errnum); 290 | perror("Error printed by perror"); 291 | fprintf(stderr, "Error get nic address: %s\n", strerror( errnum )); 292 | } 293 | 294 | sleep(10); 295 | 296 | alarm(10); 297 | current_state = EAPOL_START; 298 | 299 | send_eap_frame(EAPOL_START, NULL); 300 | } 301 | 302 | 303 | 304 | //------function---------------------------------------------------------- 305 | // name: 306 | // HandleSigalrm 307 | // description: 308 | // signal handler 函数, 通过 signal(alarm) 函数,查询 jmuSupplicant 309 | // 此时的运行状态。根据当前运行状态, 做出对应的动作。 310 | // 311 | // ONLINE: 认证并登录成功,发送心跳包保持在线。 312 | // EAP_FAILURE: 认证并登录成功后,收到服务器发送的下线信息。退出程序 313 | // EAPOL_START: 已发送认证 frame,但未收到服务器的响应。 314 | //------------------------------------------------------------------------ 315 | void HandleSigalrm(int sig, siginfo_t *siginfo, void *context) 316 | { 317 | extern SEND_FRAME_TYPE current_state; 318 | extern pcap_t *descr; 319 | 320 | switch(current_state) { 321 | case ONLINE: 322 | // send_ethernet_frame(KEEP_ONLINE, eapol_heartbeat); 323 | KeepOnline(); 324 | 325 | // Logs here 326 | openlog(NULL, LOG_PID|LOG_CONS, LOG_USER); 327 | syslog(LOG_INFO, "Send an eapol heartbeat frame..."); 328 | closelog(); 329 | 330 | alarm(30); 331 | break; 332 | 333 | case EAP_FAILURE: 334 | pcap_breakloop(descr); // force pcap_loop() function return rather than looping 335 | break; 336 | 337 | case EAPOL_START: 338 | fprintf(stderr, "已发送认证信息,但未收到服务器响应包,请检查网络连接是否正常\n"); 339 | pcap_breakloop(descr); // force pcap_loop() function return rather than looping 340 | break; 341 | 342 | default: 343 | break; 344 | } 345 | 346 | return; 347 | } 348 | 349 | //------function---------------------------------------------------------- 350 | // name: 351 | // KeepOnline 352 | // description: 353 | // 发送心跳包保持在线 354 | //------------------------------------------------------------------------ 355 | void KeepOnline() 356 | { 357 | extern SEND_FRAME_TYPE current_state; 358 | 359 | if(current_state == ONLINE) 360 | { 361 | // Logs here 362 | openlog(NULL, LOG_PID|LOG_CONS, LOG_USER); 363 | syslog(LOG_INFO, "Send an eapol heartbeat frame..."); 364 | closelog(); 365 | 366 | send_eap_frame(ONLINE, NULL); 367 | }else exit(1); 368 | 369 | return; 370 | } 371 | 372 | 373 | //------function---------------------------------------------------------- 374 | // name: 375 | // DaemonInit 376 | // description: 377 | // daemon 模式初始化, 用于后台运行.功能正常 378 | // 已经弃用,转为使用Linux库函数daemon() 379 | //------------------------------------------------------------------------ 380 | 381 | /* 382 | void DaemonInit() 383 | { 384 | pid_t pid, sid; 385 | 386 | // Fork off the parent process 387 | pid = fork(); 388 | // Error occur 389 | if (pid == -1) { 390 | exit(EXIT_FAILURE); 391 | } 392 | // If we get a good child pid, then 393 | // we can exit the parent process 394 | if (pid > 0) { 395 | exit(EXIT_SUCCESS); 396 | } 397 | 398 | // Change the file mode mask 399 | umask(0); 400 | 401 | // Create a new SID for the child process 402 | sid = setsid(); 403 | // Error occur 404 | if (sid == -1) { 405 | // Log the failure 406 | exit(EXIT_FAILURE); 407 | } 408 | 409 | // change the current working directory 410 | if ((chdir("/")) < 0) { 411 | exit(EXIT_FAILURE); 412 | } 413 | 414 | // Close out the standard file descriptors 415 | close(STDIN_FILENO); 416 | close(STDOUT_FILENO); 417 | close(STDERR_FILENO); 418 | 419 | // Daemon-specific initialization goes here 420 | 421 | return; 422 | } 423 | */ 424 | 425 | 426 | //------function---------------------------------------------------------- 427 | // name: 428 | // LockRegister 429 | // description: 430 | // 初始化锁文件参数 431 | //------------------------------------------------------------------------ 432 | int LockRegister(int fd, int cmd, int type, off_t offset, int whence, off_t len) 433 | { 434 | struct flock lock; 435 | 436 | lock.l_type = type; // F_RDLCK, F_WRLCK, F_UNLCK 437 | lock.l_start = offset; // byte offset, relative to l_whence 438 | lock.l_whence = whence; // SEEK_SET, SEEK_CUR, SEEK_END 439 | lock.l_len = len; // #bytes (0 means to EOF) 440 | 441 | return(fcntl(fd, cmd, &lock)); // manipulate file descriptor 442 | } 443 | 444 | 445 | //------function---------------------------------------------------------- 446 | // name: 447 | // LockTest 448 | // description: 449 | // 检测当前是否有 jmuSupplicant 实例正在运行 450 | //------------------------------------------------------------------------ 451 | pid_t LockTest(int fd, int type, off_t offset, int whence, off_t len) 452 | { 453 | struct flock lock; 454 | 455 | lock.l_type = type; // F_RDLCK or F_WRLCK 456 | lock.l_start = offset; // byte offset, relative to l_whence 457 | lock.l_whence = whence; // SEEK_SET, SEEK_CUR, SEEK_END 458 | lock.l_len = len; // #bytes (0 means to EOF) 459 | 460 | if (fcntl(fd, F_GETLK, &lock) < 0) { 461 | fprintf(stderr, "fcntl error\n"); 462 | exit(EXIT_FAILURE); 463 | } 464 | 465 | if (lock.l_type == F_UNLCK) 466 | return 0; // false, region isn't locked by another proc 467 | return lock.l_pid; // true, return pid of lock owner 468 | } 469 | 470 | 471 | //------function---------------------------------------------------------- 472 | // name: 473 | // KillJMUSupplicant 474 | // description: 475 | // 杀死 jmuSupplicant 后台运行的进程 476 | //------------------------------------------------------------------------ 477 | int KillJMUSupplicant(int exit_flag, int fd, int type, off_t offset, int whence, off_t len) 478 | { 479 | pid_t pid; 480 | if(exit_flag) { 481 | pid = LockTest(fd, type, offset, whence, len); 482 | if(pid > 0) { 483 | kill(pid, SIGKILL); 484 | CleanMemory(); 485 | } 486 | } 487 | 488 | return 0; 489 | } 490 | 491 | //------function---------------------------------------------------------- 492 | // name: 493 | // initiative_exit_program_with_already_running_check 494 | // description: 495 | // 用户请求杀死 jmuSupplicant 后台运行的进程 496 | // 根据锁文件判断 jmuSupplicant 的运行状态并输出到控制台 497 | //------------------------------------------------------------------------ 498 | int initiative_exit_program_with_already_running_check(int exit_flag, int fd, pid_t pid) 499 | { 500 | if(exit_flag) { 501 | if(pid > 0) { 502 | KillJMUSupplicant(exit_flag, fd, F_WRLCK, 0, SEEK_SET, 0); 503 | fprintf(stdout, "Success kill the process\n"); 504 | 505 | exit(EXIT_SUCCESS); 506 | } else { 507 | fprintf(stdout, "The process is not running\n"); 508 | 509 | exit(EXIT_SUCCESS); 510 | } 511 | } else { 512 | if(pid > 0) { 513 | fprintf(stdout, "The process is running on background\n"); 514 | 515 | exit(EXIT_SUCCESS); 516 | } 517 | } 518 | 519 | return 0; 520 | } 521 | 522 | //------function---------------------------------------------------------- 523 | // name: 524 | // CleanMemory 525 | // description: 526 | // 释放内存 527 | //------------------------------------------------------------------------ 528 | static int CleanMemory() 529 | { 530 | extern char *username; 531 | extern char *password; 532 | extern char *user_input_gateway; // 由用户设定的四个报文参数 533 | extern char *user_input_dns; // numbers-and-dots dns notation by user input 534 | extern char *user_input_ipaddr; // numbers-and-dots ip notation by user input 535 | extern char *user_input_mask; // number-and-dots mask notation by user input 536 | extern char *service_company; // login service name 537 | 538 | /* 539 | if(username != NULL) 540 | free(username); 541 | if(password != NULL) 542 | free(password); 543 | if(user_input_gateway != NULL) 544 | free(user_input_gateway); 545 | if(user_input_dns != NULL) 546 | free(user_input_dns); 547 | if(user_input_ipaddr != NULL) 548 | free(user_input_ipaddr); 549 | if(user_input_mask != NULL) 550 | free(user_input_mask); 551 | if(service_company != NULL) 552 | free(service_company); 553 | */ 554 | return 0; 555 | } 556 | 557 | -------------------------------------------------------------------------------- /src/init.c: -------------------------------------------------------------------------------- 1 | // 2 | //================================================================== 3 | // 4 | // Filename: init.c 5 | // 6 | // Description: 7 | // 8 | // Version: 1.0 9 | // Created: 04/28/2018 06:12:18 A.M. 10 | // Revision: none 11 | // Compiler: gcc 12 | // 13 | // Author: codingstory, codingstory.tw@gmail.com 14 | // 15 | // 1、根据用户的输入参数初始化认证信息(username,password, 16 | // midnight mode, background running, service name and so on) 17 | // 2、初始化网络设备信息(device name, device ipaddr,netmask, MAC), 18 | // 网络设备用于发送和接收认证数据 19 | // 20 | //================================================================== 21 | // 22 | 23 | 24 | #include "init.h" 25 | 26 | unsigned int background_running = 0; // 默认不会后台运行 27 | unsigned int multiple_running = 0; // 默认只允许一个 jmuSupplicant 实例运行 28 | unsigned int midnight = 0; // 断网后登录 29 | unsigned int exit_flag = 0; // 用户主动杀死后台运行的 jmuSupplicant 进程 30 | char *username = NULL; 31 | char *password = NULL; 32 | char *user_input_gateway = NULL; // user input dns dotted pair address 33 | char *user_input_dns = NULL; 34 | char *user_input_ipaddr = NULL; 35 | char *user_input_mask = NULL; 36 | char *service_company = NULL; // 服务名,0教育网,1联通,2移动,3电信 37 | uint8_t *service_name = NULL; // Hex 格式服务名, 用于填充到认证 frame 中 38 | char *network_interface_card_name = NULL; // 用于存储用户输入的网卡名 39 | unsigned int username_length = 0; 40 | unsigned int password_length = 0; 41 | unsigned int ipaddr_length = 0; 42 | unsigned int mask_length = 0; 43 | NIC_STRUCT nic_info; // 网络设备信息结构体,包含 ip, netmask, gateway 等等 44 | 45 | // 保存参数信息, 用于登录失败重新登陆 46 | char *username_bp = NULL; 47 | char *password_bp = NULL; 48 | char *user_input_ipaddr_bp = NULL; 49 | char *user_input_mask_bp = NULL; 50 | char *service_company_bp = NULL; 51 | unsigned int midnight_bp = 0; 52 | 53 | 54 | //------function---------------------------------------------------------- 55 | // name: 56 | // init_login_config 57 | // description: 58 | // 根据用户的输入参数初始化认证信息 59 | //------------------------------------------------------------------------ 60 | void init_login_config() 61 | { 62 | // 初始化 NIC_STRUCT structure 63 | nic_info.ipaddr.s_addr = -1; 64 | nic_info.netmask.s_addr = -1; 65 | nic_info.gateway.s_addr = -1; 66 | nic_info.dns.s_addr = -1; 67 | memset(nic_info.nic_MAC, '\0', sizeof(ETHER_ADDR_LEN * sizeof(uint8_t))); 68 | 69 | // 判断用户是否输入用户名和密码 70 | if(username == NULL || password == NULL) { 71 | fprintf(stderr, "似乎没有输入认证帐号或密码.\n" 72 | "尝试运行 'sudo ./jmuSupplicant --help' 获取使用方法。\n"); 73 | exit(EXIT_FAILURE); 74 | } 75 | username_length = strlen(username); 76 | password_length = strlen(password); 77 | 78 | // 如果用户指定了断网登录模式,保存下来用以认证失败时重新认证 79 | if(midnight == 1) 80 | { 81 | midnight_bp = midnight; 82 | } 83 | 84 | if(network_interface_card_name != NULL) 85 | { 86 | memset(nic_info.nic_name, '\0', sizeof(NIC_SIZE * sizeof(char))); 87 | memcpy(nic_info.nic_name, network_interface_card_name, sizeof(nic_info.nic_name)); 88 | } 89 | 90 | #if defined(DEBUG) 91 | fprintf(stdout, "the received password from user input is : %s\n" 92 | "and the password length is %d\n", password, password_length); 93 | #endif 94 | 95 | init_gateway(); 96 | init_DNS(); 97 | init_netmask(); 98 | init_ipaddr(); 99 | init_service_name(); 100 | 101 | return; 102 | } 103 | 104 | //------function---------------------------------------------------------- 105 | // name: 106 | // InitDevice 107 | // description: 108 | // 初始化网络设备,获取网络设备 name,ipaddr,netmask,MAC 109 | // 并填充到 NIC_STRUCT 中 110 | //------------------------------------------------------------------------ 111 | void init_device() 112 | { 113 | 114 | if(network_interface_card_name == NULL && nic_info.nic_name != NULL) { // specify a network interface card 115 | memset(nic_info.nic_name, '\0', sizeof(NIC_SIZE * sizeof(char))); 116 | if(strlen(nic_info.nic_name) == 0) { 117 | init_NIC_name(&nic_info); 118 | printf("network interface card name: %s\n", nic_info.nic_name); 119 | } 120 | }else printf("network interface card name: %s\n", nic_info.nic_name); 121 | 122 | // system(dhcp_script); 123 | memset(nic_info.nic_MAC, '\0', sizeof(ETHER_ADDR_LEN * sizeof(uint8_t))); 124 | if(init_NIC_address(&nic_info) == -1) { // get network interface card MAC, ip, mask 125 | int errnum = errno; 126 | fprintf(stderr, "Value of errno: %d\n", errnum); 127 | perror("Error printed by perror"); 128 | fprintf(stderr, "Error get nic address: %s\n", strerror( errnum )); 129 | 130 | exit(1); 131 | } 132 | 133 | PrintInitConfig(); 134 | return; 135 | } 136 | 137 | //------function---------------------------------------------------------- 138 | // name: 139 | // InitGateway 140 | // description: 141 | // If user has inputted Gateway, converts it from the IPv4 142 | // numbers-and-dots notation into binary form (in network byte 143 | // order), and stores it in the structure that 144 | // &nic_info.gateway points to. 145 | //------------------------------------------------------------------------ 146 | static void init_gateway() 147 | { 148 | if(user_input_gateway != NULL) { 149 | int s, domain; 150 | domain = AF_INET; 151 | 152 | if(inet_aton(user_input_gateway, &nic_info.gateway) == 0) { 153 | fprintf(stderr, "Invalid gateway address\n"); 154 | exit(EXIT_FAILURE); 155 | } 156 | } 157 | 158 | return; 159 | } 160 | 161 | static void init_DNS() 162 | { 163 | // the same is true for dns 164 | if(user_input_dns != NULL) { 165 | int s, domain; 166 | domain = AF_INET; 167 | 168 | if(inet_aton(user_input_dns, &nic_info.dns) == 0) { 169 | fprintf(stderr, "Invalid DNS server address\n"); 170 | exit(EXIT_FAILURE); 171 | } 172 | } 173 | 174 | return; 175 | } 176 | 177 | static void init_netmask() 178 | { 179 | // the same is true for netmask 180 | if(user_input_mask != NULL) { 181 | int s, domain; 182 | domain = AF_INET; 183 | if(inet_aton(user_input_mask, &nic_info.netmask) == 0) { 184 | fprintf(stderr, "Invalid netmask address\n"); 185 | exit(EXIT_FAILURE); 186 | } 187 | // 如果用户指定了 netmask 地址,保存下来用以认证失败时重新认证 188 | mask_length = strlen(user_input_mask); 189 | user_input_mask_bp = (char*)calloc(mask_length + 1, sizeof(char)); 190 | memcpy(user_input_mask_bp, user_input_mask, mask_length + 1); 191 | } 192 | 193 | return; 194 | } 195 | 196 | static void init_ipaddr() 197 | { 198 | // the same is true for ipaddr 199 | if(user_input_ipaddr != NULL) { 200 | int s, domain; 201 | domain = AF_INET; 202 | if(inet_aton(user_input_ipaddr, &nic_info.ipaddr) == 0) { 203 | fprintf(stderr, "Invalid ip address\n"); 204 | exit(EXIT_FAILURE); 205 | } 206 | // 如果用户指定了 ip 地址,保存下来用以认证失败时重新认证 207 | ipaddr_length = strlen(user_input_ipaddr); 208 | user_input_ipaddr_bp = (char*)calloc(ipaddr_length + 1, sizeof(char)); 209 | memcpy(user_input_ipaddr_bp, user_input_ipaddr, ipaddr_length + 1); 210 | } 211 | 212 | return; 213 | } 214 | 215 | static void init_service_name() 216 | { 217 | if(service_company == NULL) { // 用户未输入服务名,默认以'教育网'登录 218 | service_name = (uint8_t*)malloc(DEFAULT_SERVICE_NAME_SIZE * sizeof(uint8_t)); 219 | memset(service_name, 0x00, DEFAULT_SERVICE_NAME_SIZE); 220 | memcpy(service_name, SERVICE_EDUCATION, SERVICE_EDUCATION_LENGTH); 221 | } else { 222 | // 用户指定了'服务名',保存下来用以认证失败时重新认证 223 | service_company_bp = (char*)calloc(2, sizeof(char)); 224 | memcpy(service_company_bp, service_company, 2); 225 | 226 | // 判断'服务名'具体为哪一个 227 | unsigned int integer_type_service_company = atoi(service_company); 228 | integer_type_service_company %= 4; 229 | switch(integer_type_service_company) { 230 | // Education network 231 | case 0: 232 | service_name = (uint8_t*)malloc(DEFAULT_SERVICE_NAME_SIZE * sizeof(uint8_t)); 233 | memset(service_name, 0x00, DEFAULT_SERVICE_NAME_SIZE); 234 | memcpy(service_name, SERVICE_EDUCATION, SERVICE_EDUCATION_LENGTH); 235 | break; 236 | // China Unicom network 237 | case 1: 238 | service_name = (uint8_t*)malloc(DEFAULT_SERVICE_NAME_SIZE * sizeof(uint8_t)); 239 | memset(service_name, 0x00, DEFAULT_SERVICE_NAME_SIZE); 240 | memcpy(service_name, SERVICE_CHINA_UNICOM, SERVICE_CHINA_UNICOM_LENGTH); 241 | break; 242 | // China mobile network 243 | case 2: 244 | service_name = (uint8_t*)malloc(DEFAULT_SERVICE_NAME_SIZE * sizeof(uint8_t)); 245 | memset(service_name, 0x00, DEFAULT_SERVICE_NAME_SIZE); 246 | memcpy(service_name, SERVICE_CHINA_MOBILE,SERVICE_CHINA_MOBILE_LENGTH); 247 | break; 248 | // China Telecom network 249 | case 3: 250 | service_name = (uint8_t*)malloc(DEFAULT_SERVICE_NAME_SIZE * sizeof(uint8_t)); 251 | memset(service_name, 0x00, DEFAULT_SERVICE_NAME_SIZE); 252 | memcpy(service_name, SERVICE_CHINA_TELECOM, SERVICE_CHINA_TELECOM_LENGTH); 253 | break; 254 | } 255 | } 256 | 257 | return; 258 | } 259 | 260 | 261 | //------function---------------------------------------------------------- 262 | // name: 263 | // init_NIC_name 264 | // description: 265 | // 获取并显示电脑上所有网络设备名称,用户选择后存储名称至 NIC_STRUCT 266 | //------------------------------------------------------------------------ 267 | int init_NIC_name(NIC_STRUCT *nic_info) 268 | { 269 | struct ifaddrs *ifaddr, *ifa; 270 | int family, s, n; 271 | char hbuf[NIC_MAXHOST]; 272 | size_t available_adapter_num = 0, choosed_adapter = 0; // 可选的网络设备数量; 被选择的网络设备序号 273 | char **available_adapter_name = NULL, **more_available_adapter_names = NULL; // 可选的网络设备名; realooc()函数需要用到的指针 274 | 275 | if (getifaddrs(&ifaddr) == -1) { 276 | printf("%s", strerror(errno)); 277 | } 278 | 279 | /* Walk through linked list, maintaining head pointer so we 280 | * can free list later 281 | */ 282 | for(ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { 283 | if (ifa->ifa_addr == NULL) 284 | continue; 285 | family = ifa->ifa_addr->sa_family; 286 | if(ifa->ifa_flags & IFF_LOOPBACK) 287 | continue; 288 | if( family == AF_INET ) { // only use ipv4 289 | s = getnameinfo(ifa->ifa_addr, 290 | (family == AF_INET) ? sizeof(struct sockaddr_in) : 291 | sizeof(struct sockaddr_in6), 292 | hbuf, NIC_MAXHOST, 293 | NULL, 0, NI_NUMERICHOST); 294 | if(s != 0) { 295 | continue; 296 | } else { 297 | if(strlen(ifa->ifa_name) >= IFNAMSIZ) // avoid adapter name exceed sizeof( ifr.ifr_name ) 298 | continue; 299 | available_adapter_num++; 300 | /* 301 | * (re)allocating adapters name array for user to chose 302 | */ 303 | if(available_adapter_name == NULL) { 304 | available_adapter_name = (char**)calloc(1, sizeof(char*)); 305 | if(available_adapter_name == NULL) { 306 | printf("Error (re)allocating adapters name memory (char **)"); 307 | exit(EXIT_FAILURE); 308 | } 309 | available_adapter_name[(int)available_adapter_num - 1] = (char*)calloc(IFNAMSIZ, sizeof(char)); 310 | if(available_adapter_name[(int)available_adapter_num - 1] == NULL) { 311 | printf("Error (re)allocating adapters name memory (available_adapter_name[0])"); 312 | exit(EXIT_FAILURE); 313 | } 314 | } else { 315 | more_available_adapter_names = (char**)realloc(available_adapter_name, available_adapter_num * sizeof(char*)); 316 | if (more_available_adapter_names != NULL) { 317 | available_adapter_name = more_available_adapter_names; 318 | available_adapter_name[(int)available_adapter_num - 1] = (char*)calloc(IFNAMSIZ, sizeof(char)); 319 | if(available_adapter_name[(int)available_adapter_num - 1] == NULL) { 320 | printf("Error (re)allocating adapters name memory (available_adapter_name[%zu])", available_adapter_num - 1); 321 | exit(EXIT_FAILURE); 322 | } 323 | 324 | } else { 325 | free (available_adapter_name); 326 | printf("Error reallocating adapters name memory"); 327 | exit(EXIT_FAILURE); 328 | } 329 | } 330 | 331 | strcpy(available_adapter_name[available_adapter_num - 1], ifa->ifa_name); // strcpy() the device name 332 | printf("[ %zu ] %s <%s>\n", available_adapter_num, ifa->ifa_name, hbuf); // 打印到控制台供用户选择输入 333 | } 334 | } else { 335 | continue; 336 | } 337 | } 338 | 339 | // 未找到可用的网络设备 340 | if(available_adapter_num == 0) { 341 | freeifaddrs(ifaddr); 342 | ifaddr = NULL; 343 | printf("No available network adapter\n"); 344 | 345 | return -1; // failed to get adapter 346 | } else { 347 | printf("please enter 1 ~ %zu to choose a network adapter: ", available_adapter_num); 348 | scanf("%zu", &choosed_adapter); 349 | choosed_adapter %= available_adapter_num; // avoid illegal input 350 | abs( choosed_adapter ); 351 | if(choosed_adapter != 0) { 352 | choosed_adapter -= 1; 353 | } else { 354 | choosed_adapter = abs( available_adapter_num ) - 1; 355 | } 356 | 357 | // 存储用户选择的网络设备名 358 | memcpy(nic_info->nic_name, available_adapter_name[choosed_adapter], sizeof(nic_info->nic_name)); 359 | } 360 | 361 | return 0; 362 | } 363 | 364 | //------function---------------------------------------------------------- 365 | // name: 366 | // init_NIC_address 367 | // description: 368 | // 获取网络设备上的地址, ip, MAC, mask, 存储至 NIC_STRUCT structure 369 | //---------------------------------------------------------------- 370 | int init_NIC_address(NIC_STRUCT *nic_info) 371 | { 372 | struct ifreq ifr; // ifreq structure contains network interface infos 373 | char if_name[IFNAMSIZ] = ""; 374 | memcpy(if_name, nic_info->nic_name, sizeof(if_name)); 375 | unsigned char host_MAC[MAC_LENGTH] = ""; // Ethernet MAC address 376 | size_t if_name_len = strlen( if_name ); // ifr_name is a fixed-length buffer, be care about it 377 | int fd = socket(AF_UNIX, SOCK_DGRAM, 0); // function ioctl() need a socket descriptor as variable 378 | extern char *user_input_ipaddr; 379 | extern char *user_input_mask; 380 | 381 | // 382 | // Get the host( Ethernet interface ) MAC address in C 383 | // 384 | if(fd == -1) { 385 | printf("%s", strerror(errno)); 386 | printf("create socket failed\n"); 387 | 388 | return -1; 389 | } 390 | if( if_name_len < sizeof( ifr.ifr_name ) ) { 391 | memcpy( ifr.ifr_name, if_name, if_name_len ); 392 | ifr.ifr_name[if_name_len] = 0; 393 | } else { 394 | printf("interface name is too long"); 395 | 396 | return -1; 397 | } 398 | 399 | #if defined(DEBUG) 400 | printf("Network Interface Name: %s\n", ifr.ifr_name); 401 | #endif 402 | 403 | #ifdef SIOCGIFHWADDR 404 | // once have ifreq structure and socket descriptor then we can invoke ioctl() 405 | if ( ioctl( fd, SIOCGIFHWADDR, &ifr ) == -1 ) { 406 | int temp_errno = errno; 407 | close( fd ); 408 | printf("%s", strerror(temp_errno)); 409 | printf(" get host MAC address procedure error\n"); 410 | return -1; 411 | } 412 | close( fd ); 413 | // make sure the type of the network interface we got is a Ethernet interface 414 | if ( ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER ) { 415 | printf("not an Ethernet interface\n"); 416 | 417 | return -1; 418 | } 419 | memcpy( host_MAC, ifr.ifr_hwaddr.sa_data, 6); 420 | memcpy(nic_info->nic_MAC, ifr.ifr_hwaddr.sa_data, MAC_LENGTH); 421 | #endif 422 | #if defined(DEBUG) 423 | printf("MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n", 424 | host_MAC[0], host_MAC[1], host_MAC[2], host_MAC[3], host_MAC[4], host_MAC[5]); 425 | #endif 426 | 427 | // 428 | // Get the IP address of a network interface in C using SIOCGIFADDR 429 | // 430 | if(user_input_ipaddr == NULL) { 431 | fd = socket(AF_INET, SOCK_DGRAM, 0); 432 | struct sockaddr_in* ipaddr; 433 | if (fd == -1) { 434 | printf("%s", strerror(errno)); 435 | 436 | return -1; 437 | } 438 | #ifdef SIOCGIFADDR 439 | if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) { 440 | int temp_errno = errno; 441 | close(fd); 442 | printf("%s\n", strerror(temp_errno)); 443 | printf("get ip address failed\n"); 444 | 445 | return -1; 446 | } 447 | close(fd); 448 | ipaddr = (struct sockaddr_in*)&ifr.ifr_addr; 449 | //nic_info->ipaddr = ipaddr->sin_addr.s_addr; 450 | memcpy(&nic_info->ipaddr, &ipaddr->sin_addr, sizeof(struct in_addr)); 451 | #endif 452 | #if defined(DEBUG) 453 | printf("IP address: %s\n", inet_ntoa(ipaddr->sin_addr)); // ntoa : network to ASCII 454 | #endif 455 | } 456 | #if defined(DEBUG) 457 | printf("IP address: %s\n", user_input_ipaddr); // ntoa : network to ASCII 458 | #endif 459 | 460 | // 461 | // Get the MASK address of a network interface in C using SIOCGIFNETMASK 462 | // 463 | if(user_input_mask == NULL) { 464 | fd = socket(AF_INET, SOCK_DGRAM, 0); 465 | struct sockaddr_in* netmask; 466 | if(fd == -1) { 467 | printf("%s", strerror(errno)); 468 | printf("create fd failed in GET MASK address function\n"); 469 | 470 | return -1; 471 | } 472 | #ifdef SIOCGIFNETMASK 473 | if(ioctl(fd, SIOCGIFNETMASK, &ifr) == -1) { 474 | int temp_errno = errno; 475 | close(fd); 476 | printf("%s\n", strerror(temp_errno)); 477 | printf("get MASK address failed\n"); 478 | 479 | return -1; 480 | } 481 | close(fd); 482 | netmask = (struct sockaddr_in*)&ifr.ifr_addr; 483 | //nic_info->netmask = netmask->sin_addr.s_addr; 484 | memcpy(&nic_info->netmask, &netmask->sin_addr, sizeof(struct in_addr)); 485 | #endif 486 | #if defined(DEBUG) 487 | printf("Network Mask: %s\n", inet_ntoa(netmask->sin_addr)); 488 | #endif 489 | } 490 | #if defined(DEBUG) 491 | printf("Network Mask: %s\n", user_input_mask); 492 | #endif 493 | 494 | return 0; 495 | } 496 | 497 | 498 | static void PrintInitConfig() 499 | { 500 | char* isp_name = NULL; 501 | printf("\nUserName:\t%s\n", username); 502 | printf("Network Card:\t%s\n", nic_info.nic_name); 503 | unsigned int integer_type_service_company = atoi(service_company); 504 | integer_type_service_company %= 4; 505 | switch(integer_type_service_company) { 506 | case 0: 507 | isp_name = "教育网接入"; 508 | break; 509 | case 1: 510 | isp_name = "联通宽带接入"; 511 | break; 512 | case 2: 513 | isp_name = "移动宽带接入"; 514 | break; 515 | case 3: 516 | isp_name = "电信宽带接入"; 517 | break; 518 | } 519 | printf("service name:\t%s\n\n\n", isp_name); 520 | return; 521 | } 522 | 523 | -------------------------------------------------------------------------------- /src/mentohust_encryption/rjtiger_sbox.c: -------------------------------------------------------------------------------- 1 | /* tiger_sbox.c - S-Box for Tiger hash function 2 | * 3 | * Copyright: 2007-2012 Aleksey Kravchenko 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! 15 | */ 16 | #include "byte_order.h" 17 | 18 | /* Four S-boxes used for table lookups by Tiger hash function. 8Kb in total. */ 19 | uint64_t rhash_tiger_sboxes[4][256] = { 20 | { 21 | I64(0x02aab17cf7e90c5e), I64(0xac424b03e243a8ec) 22 | , I64(0x72cd5be30dd5fcd3), I64(0x6d019b93f6f97f3a) 23 | , I64(0xcd9978ffd21f9193), I64(0x7573a1c9708029e2) 24 | , I64(0xb164326b922a83c3), I64(0x46883eee04915870) 25 | , I64(0xeaace3057103ece6), I64(0xc54169b808a3535c) 26 | , I64(0x4ce754918ddec47c), I64(0x0aa2f4dfdc0df40c) 27 | , I64(0x10b76f18a74dbefa), I64(0xc6ccb6235ad1ab6a) 28 | , I64(0x13726121572fe2ff), I64(0x1a488c6f199d921e) 29 | , I64(0x4bc9f9f4da0007ca), I64(0x26f5e6f6e85241c7) 30 | , I64(0x859079dbea5947b6), I64(0x4f1885c5c99e8c92) 31 | , I64(0xd78e761ea96f864b), I64(0x8e36428c52b5c17d) 32 | , I64(0x69cf6827373063c1), I64(0xb607c93d9bb4c56e) 33 | , I64(0x7d820e760e76b5ea), I64(0x645c9cc6f07fdc42) 34 | , I64(0xbf38a078243342e0), I64(0x5f6b343c9d2e7d04) 35 | , I64(0xf2c28aeb600b0ec6), I64(0x6c0ed85f7254bcac) 36 | , I64(0x71592281a4db4fe5), I64(0x1967fa69ce0fed9f) 37 | , I64(0xfd5293f8b96545db), I64(0xc879e9d7f2a7600b) 38 | , I64(0x860248920193194e), I64(0xa4f9533b2d9cc0b3) 39 | , I64(0x9053836c15957613), I64(0xdb6dcf8afc357bf1) 40 | , I64(0x18beea7a7a370f57), I64(0x037117ca50b99066) 41 | , I64(0x6ab30a9774424a35), I64(0xf4e92f02e325249b) 42 | , I64(0x7739db07061ccae1), I64(0xd8f3b49ceca42a05) 43 | , I64(0xbd56be3f51382f73), I64(0x45faed5843b0bb28) 44 | , I64(0x1c813d5c11bf1f83), I64(0x8af0e4b6d75fa169) 45 | , I64(0x33ee18a487ad9999), I64(0x3c26e8eab1c94410) 46 | , I64(0xb510102bc0a822f9), I64(0x141eef310ce6123b) 47 | , I64(0xfc65b90059ddb154), I64(0xe0158640c5e0e607) 48 | , I64(0x884e079826c3a3cf), I64(0x930d0d9523c535fd) 49 | , I64(0x35638d754e9a2b00), I64(0x4085fccf40469dd5) 50 | , I64(0xc4b17ad28be23a4c), I64(0xcab2f0fc6a3e6a2e) 51 | , I64(0x2860971a6b943fcd), I64(0x3dde6ee212e30446) 52 | , I64(0x6222f32ae01765ae), I64(0x5d550bb5478308fe) 53 | , I64(0xa9efa98da0eda22a), I64(0xc351a71686c40da7) 54 | , I64(0x1105586d9c867c84), I64(0xdcffee85fda22853) 55 | , I64(0xccfbd0262c5eef76), I64(0xbaf294cb8990d201) 56 | , I64(0xe69464f52afad975), I64(0x94b013afdf133e14) 57 | , I64(0x06a7d1a32823c958), I64(0x6f95fe5130f61119) 58 | , I64(0xd92ab34e462c06c0), I64(0xed7bde33887c71d2) 59 | , I64(0x79746d6e6518393e), I64(0x5ba419385d713329) 60 | , I64(0x7c1ba6b948a97564), I64(0x31987c197bfdac67) 61 | , I64(0xde6c23c44b053d02), I64(0x581c49fed002d64d) 62 | , I64(0xdd474d6338261571), I64(0xaa4546c3e473d062) 63 | , I64(0x928fce349455f860), I64(0x48161bbacaab94d9) 64 | , I64(0x63912430770e6f68), I64(0x6ec8a5e602c6641c) 65 | , I64(0x87282515337ddd2b), I64(0x2cda6b42034b701b) 66 | , I64(0xb03d37c181cb096d), I64(0xe108438266c71c6f) 67 | , I64(0x2b3180c7eb51b255), I64(0xdf92b82f96c08bbc) 68 | , I64(0x5c68c8c0a632f3ba), I64(0x5504cc861c3d0556) 69 | , I64(0xabbfa4e55fb26b8f), I64(0x41848b0ab3baceb4) 70 | , I64(0xb334a273aa445d32), I64(0xbca696f0a85ad881) 71 | , I64(0x24f6ec65b528d56c), I64(0x0ce1512e90f4524a) 72 | , I64(0x4e9dd79d5506d35a), I64(0x258905fac6ce9779) 73 | , I64(0x2019295b3e109b33), I64(0xf8a9478b73a054cc) 74 | , I64(0x2924f2f934417eb0), I64(0x3993357d536d1bc4) 75 | , I64(0x38a81ac21db6ff8b), I64(0x47c4fbf17d6016bf) 76 | , I64(0x1e0faadd7667e3f5), I64(0x7abcff62938beb96) 77 | , I64(0xa78dad948fc179c9), I64(0x8f1f98b72911e50d) 78 | , I64(0x61e48eae27121a91), I64(0x4d62f7ad31859808) 79 | , I64(0xeceba345ef5ceaeb), I64(0xf5ceb25ebc9684ce) 80 | , I64(0xf633e20cb7f76221), I64(0xa32cdf06ab8293e4) 81 | , I64(0x985a202ca5ee2ca4), I64(0xcf0b8447cc8a8fb1) 82 | , I64(0x9f765244979859a3), I64(0xa8d516b1a1240017) 83 | , I64(0x0bd7ba3ebb5dc726), I64(0xe54bca55b86adb39) 84 | , I64(0x1d7a3afd6c478063), I64(0x519ec608e7669edd) 85 | , I64(0x0e5715a2d149aa23), I64(0x177d4571848ff194) 86 | , I64(0xeeb55f3241014c22), I64(0x0f5e5ca13a6e2ec2) 87 | , I64(0x8029927b75f5c361), I64(0xad139fabc3d6e436) 88 | , I64(0x0d5df1a94ccf402f), I64(0x3e8bd948bea5dfc8) 89 | , I64(0xa5a0d357bd3ff77e), I64(0xa2d12e251f74f645) 90 | , I64(0x66fd9e525e81a082), I64(0x2e0c90ce7f687a49) 91 | , I64(0xc2e8bcbeba973bc5), I64(0x000001bce509745f) 92 | , I64(0x423777bbe6dab3d6), I64(0xd1661c7eaef06eb5) 93 | , I64(0xa1781f354daacfd8), I64(0x2d11284a2b16affc) 94 | , I64(0xf1fc4f67fa891d1f), I64(0x73ecc25dcb920ada) 95 | , I64(0xae610c22c2a12651), I64(0x96e0a810d356b78a) 96 | , I64(0x5a9a381f2fe7870f), I64(0xd5ad62ede94e5530) 97 | , I64(0xd225e5e8368d1427), I64(0x65977b70c7af4631) 98 | , I64(0x99f889b2de39d74f), I64(0x233f30bf54e1d143) 99 | , I64(0x9a9675d3d9a63c97), I64(0x5470554ff334f9a8) 100 | , I64(0x166acb744a4f5688), I64(0x70c74caab2e4aead) 101 | , I64(0xf0d091646f294d12), I64(0x57b82a89684031d1) 102 | , I64(0xefd95a5a61be0b6b), I64(0x2fbd12e969f2f29a) 103 | , I64(0x9bd37013feff9fe8), I64(0x3f9b0404d6085a06) 104 | , I64(0x4940c1f3166cfe15), I64(0x09542c4dcdf3defb) 105 | , I64(0xb4c5218385cd5ce3), I64(0xc935b7dc4462a641) 106 | , I64(0x3417f8a68ed3b63f), I64(0xb80959295b215b40) 107 | , I64(0xf99cdaef3b8c8572), I64(0x018c0614f8fcb95d) 108 | , I64(0x1b14accd1a3acdf3), I64(0x84d471f200bb732d) 109 | , I64(0xc1a3110e95e8da16), I64(0x430a7220bf1a82b8) 110 | , I64(0xb77e090d39df210e), I64(0x5ef4bd9f3cd05e9d) 111 | , I64(0x9d4ff6da7e57a444), I64(0xda1d60e183d4a5f8) 112 | , I64(0xb287c38417998e47), I64(0xfe3edc121bb31886) 113 | , I64(0xc7fe3ccc980ccbef), I64(0xe46fb590189bfd03) 114 | , I64(0x3732fd469a4c57dc), I64(0x7ef700a07cf1ad65) 115 | , I64(0x59c64468a31d8859), I64(0x762fb0b4d45b61f6) 116 | , I64(0x155baed099047718), I64(0x68755e4c3d50baa6) 117 | , I64(0xe9214e7f22d8b4df), I64(0x2addbf532eac95f4) 118 | , I64(0x32ae3909b4bd0109), I64(0x834df537b08e3450) 119 | , I64(0xfa209da84220728d), I64(0x9e691d9b9efe23f7) 120 | , I64(0x0446d288c4ae8d7f), I64(0x7b4cc524e169785b) 121 | , I64(0x21d87f0135ca1385), I64(0xcebb400f137b8aa5) 122 | , I64(0x272e2b66580796be), I64(0x3612264125c2b0de) 123 | , I64(0x057702bdad1efbb2), I64(0xd4babb8eacf84be9) 124 | , I64(0x91583139641bc67b), I64(0x8bdc2de08036e024) 125 | , I64(0x603c8156f49f68ed), I64(0xf7d236f7dbef5111) 126 | , I64(0x9727c4598ad21e80), I64(0xa08a0896670a5fd7) 127 | , I64(0xcb4a8f4309eba9cb), I64(0x81af564b0f7036a1) 128 | , I64(0xc0b99aa778199abd), I64(0x959f1ec83fc8e952) 129 | , I64(0x8c505077794a81b9), I64(0x3acaaf8f056338f0) 130 | , I64(0x07b43f50627a6778), I64(0x4a44ab49f5eccc77) 131 | , I64(0x3bc3d6e4b679ee98), I64(0x9cc0d4d1cf14108c) 132 | , I64(0x4406c00b206bc8a0), I64(0x82a18854c8d72d89) 133 | , I64(0x67e366b35c3c432c), I64(0xb923dd61102b37f2) 134 | , I64(0x56ab2779d884271d), I64(0xbe83e1b0ff1525af) 135 | , I64(0xfb7c65d4217e49a9), I64(0x6bdbe0e76d48e7d4) 136 | , I64(0x08df828745d9179e), I64(0x22ea6a9add53bd34) 137 | , I64(0xe36e141c5622200a), I64(0x7f805d1b8cb750ee) 138 | , I64(0xafe5c7a59f58e837), I64(0xe27f996a4fb1c23c) 139 | , I64(0xd3867dfb0775f0d0), I64(0xd0e673de6e88891a) 140 | , I64(0x123aeb9eafb86c25), I64(0x30f1d5d5c145b895) 141 | , I64(0xbb434a2dee7269e7), I64(0x78cb67ecf931fa38) 142 | , I64(0xf33b0372323bbf9c), I64(0x52d66336fb279c74) 143 | , I64(0x505f33ac0afb4eaa), I64(0xe8a5cd99a2cce187) 144 | , I64(0x534974801e2d30bb), I64(0x8d2d5711d5876d90) 145 | , I64(0x1f1a412891bc038e), I64(0xd6e2e71d82e56648) 146 | , I64(0x74036c3a497732b7), I64(0x89b67ed96361f5ab) 147 | , I64(0xffed95d8f1ea02a2), I64(0xe72b3bd61464d43d) 148 | , I64(0xa6300f170bdc4820), I64(0xebc18760ed78a77a) 149 | }, 150 | { 151 | I64(0xe6a6be5a05a12138), I64(0xb5a122a5b4f87c98) 152 | , I64(0x563c6089140b6990), I64(0x4c46cb2e391f5dd5) 153 | , I64(0xd932addbc9b79434), I64(0x08ea70e42015aff5) 154 | , I64(0xd765a6673e478cf1), I64(0xc4fb757eab278d99) 155 | , I64(0xdf11c6862d6e0692), I64(0xddeb84f10d7f3b16) 156 | , I64(0x6f2ef604a665ea04), I64(0x4a8e0f0ff0e0dfb3) 157 | , I64(0xa5edeef83dbcba51), I64(0xfc4f0a2a0ea4371e) 158 | , I64(0xe83e1da85cb38429), I64(0xdc8ff882ba1b1ce2) 159 | , I64(0xcd45505e8353e80d), I64(0x18d19a00d4db0717) 160 | , I64(0x34a0cfeda5f38101), I64(0x0be77e518887caf2) 161 | , I64(0x1e341438b3c45136), I64(0xe05797f49089ccf9) 162 | , I64(0xffd23f9df2591d14), I64(0x543dda228595c5cd) 163 | , I64(0x661f81fd99052a33), I64(0x8736e641db0f7b76) 164 | , I64(0x15227725418e5307), I64(0xe25f7f46162eb2fa) 165 | , I64(0x48a8b2126c13d9fe), I64(0xafdc541792e76eea) 166 | , I64(0x03d912bfc6d1898f), I64(0x31b1aafa1b83f51b) 167 | , I64(0xf1ac2796e42ab7d9), I64(0x40a3a7d7fcd2ebac) 168 | , I64(0x1056136d0afbbcc5), I64(0x7889e1dd9a6d0c85) 169 | , I64(0xd33525782a7974aa), I64(0xa7e25d09078ac09b) 170 | , I64(0xbd4138b3eac6edd0), I64(0x920abfbe71eb9e70) 171 | , I64(0xa2a5d0f54fc2625c), I64(0xc054e36b0b1290a3) 172 | , I64(0xf6dd59ff62fe932b), I64(0x3537354511a8ac7d) 173 | , I64(0xca845e9172fadcd4), I64(0x84f82b60329d20dc) 174 | , I64(0x79c62ce1cd672f18), I64(0x8b09a2add124642c) 175 | , I64(0xd0c1e96a19d9e726), I64(0x5a786a9b4ba9500c) 176 | , I64(0x0e020336634c43f3), I64(0xc17b474aeb66d822) 177 | , I64(0x6a731ae3ec9baac2), I64(0x8226667ae0840258) 178 | , I64(0x67d4567691caeca5), I64(0x1d94155c4875adb5) 179 | , I64(0x6d00fd985b813fdf), I64(0x51286efcb774cd06) 180 | , I64(0x5e8834471fa744af), I64(0xf72ca0aee761ae2e) 181 | , I64(0xbe40e4cdaee8e09a), I64(0xe9970bbb5118f665) 182 | , I64(0x726e4beb33df1964), I64(0x703b000729199762) 183 | , I64(0x4631d816f5ef30a7), I64(0xb880b5b51504a6be) 184 | , I64(0x641793c37ed84b6c), I64(0x7b21ed77f6e97d96) 185 | , I64(0x776306312ef96b73), I64(0xae528948e86ff3f4) 186 | , I64(0x53dbd7f286a3f8f8), I64(0x16cadce74cfc1063) 187 | , I64(0x005c19bdfa52c6dd), I64(0x68868f5d64d46ad3) 188 | , I64(0x3a9d512ccf1e186a), I64(0x367e62c2385660ae) 189 | , I64(0xe359e7ea77dcb1d7), I64(0x526c0773749abe6e) 190 | , I64(0x735ae5f9d09f734b), I64(0x493fc7cc8a558ba8) 191 | , I64(0xb0b9c1533041ab45), I64(0x321958ba470a59bd) 192 | , I64(0x852db00b5f46c393), I64(0x91209b2bd336b0e5) 193 | , I64(0x6e604f7d659ef19f), I64(0xb99a8ae2782ccb24) 194 | , I64(0xccf52ab6c814c4c7), I64(0x4727d9afbe11727b) 195 | , I64(0x7e950d0c0121b34d), I64(0x756f435670ad471f) 196 | , I64(0xf5add442615a6849), I64(0x4e87e09980b9957a) 197 | , I64(0x2acfa1df50aee355), I64(0xd898263afd2fd556) 198 | , I64(0xc8f4924dd80c8fd6), I64(0xcf99ca3d754a173a) 199 | , I64(0xfe477bacaf91bf3c), I64(0xed5371f6d690c12d) 200 | , I64(0x831a5c285e687094), I64(0xc5d3c90a3708a0a4) 201 | , I64(0x0f7f903717d06580), I64(0x19f9bb13b8fdf27f) 202 | , I64(0xb1bd6f1b4d502843), I64(0x1c761ba38fff4012) 203 | , I64(0x0d1530c4e2e21f3b), I64(0x8943ce69a7372c8a) 204 | , I64(0xe5184e11feb5ce66), I64(0x618bdb80bd736621) 205 | , I64(0x7d29bad68b574d0b), I64(0x81bb613e25e6fe5b) 206 | , I64(0x071c9c10bc07913f), I64(0xc7beeb7909ac2d97) 207 | , I64(0xc3e58d353bc5d757), I64(0xeb017892f38f61e8) 208 | , I64(0xd4effb9c9b1cc21a), I64(0x99727d26f494f7ab) 209 | , I64(0xa3e063a2956b3e03), I64(0x9d4a8b9a4aa09c30) 210 | , I64(0x3f6ab7d500090fb4), I64(0x9cc0f2a057268ac0) 211 | , I64(0x3dee9d2dedbf42d1), I64(0x330f49c87960a972) 212 | , I64(0xc6b2720287421b41), I64(0x0ac59ec07c00369c) 213 | , I64(0xef4eac49cb353425), I64(0xf450244eef0129d8) 214 | , I64(0x8acc46e5caf4deb6), I64(0x2ffeab63989263f7) 215 | , I64(0x8f7cb9fe5d7a4578), I64(0x5bd8f7644e634635) 216 | , I64(0x427a7315bf2dc900), I64(0x17d0c4aa2125261c) 217 | , I64(0x3992486c93518e50), I64(0xb4cbfee0a2d7d4c3) 218 | , I64(0x7c75d6202c5ddd8d), I64(0xdbc295d8e35b6c61) 219 | , I64(0x60b369d302032b19), I64(0xce42685fdce44132) 220 | , I64(0x06f3ddb9ddf65610), I64(0x8ea4d21db5e148f0) 221 | , I64(0x20b0fce62fcd496f), I64(0x2c1b912358b0ee31) 222 | , I64(0xb28317b818f5a308), I64(0xa89c1e189ca6d2cf) 223 | , I64(0x0c6b18576aaadbc8), I64(0xb65deaa91299fae3) 224 | , I64(0xfb2b794b7f1027e7), I64(0x04e4317f443b5beb) 225 | , I64(0x4b852d325939d0a6), I64(0xd5ae6beefb207ffc) 226 | , I64(0x309682b281c7d374), I64(0xbae309a194c3b475) 227 | , I64(0x8cc3f97b13b49f05), I64(0x98a9422ff8293967) 228 | , I64(0x244b16b01076ff7c), I64(0xf8bf571c663d67ee) 229 | , I64(0x1f0d6758eee30da1), I64(0xc9b611d97adeb9b7) 230 | , I64(0xb7afd5887b6c57a2), I64(0x6290ae846b984fe1) 231 | , I64(0x94df4cdeacc1a5fd), I64(0x058a5bd1c5483aff) 232 | , I64(0x63166cc142ba3c37), I64(0x8db8526eb2f76f40) 233 | , I64(0xe10880036f0d6d4e), I64(0x9e0523c9971d311d) 234 | , I64(0x45ec2824cc7cd691), I64(0x575b8359e62382c9) 235 | , I64(0xfa9e400dc4889995), I64(0xd1823ecb45721568) 236 | , I64(0xdafd983b8206082f), I64(0xaa7d29082386a8cb) 237 | , I64(0x269fcd4403b87588), I64(0x1b91f5f728bdd1e0) 238 | , I64(0xe4669f39040201f6), I64(0x7a1d7c218cf04ade) 239 | , I64(0x65623c29d79ce5ce), I64(0x2368449096c00bb1) 240 | , I64(0xab9bf1879da503ba), I64(0xbc23ecb1a458058e) 241 | , I64(0x9a58df01bb401ecc), I64(0xa070e868a85f143d) 242 | , I64(0x4ff188307df2239e), I64(0x14d565b41a641183) 243 | , I64(0xee13337452701602), I64(0x950e3dcf3f285e09) 244 | , I64(0x59930254b9c80953), I64(0x3bf299408930da6d) 245 | , I64(0xa955943f53691387), I64(0xa15edecaa9cb8784) 246 | , I64(0x29142127352be9a0), I64(0x76f0371fff4e7afb) 247 | , I64(0x0239f450274f2228), I64(0xbb073af01d5e868b) 248 | , I64(0xbfc80571c10e96c1), I64(0xd267088568222e23) 249 | , I64(0x9671a3d48e80b5b0), I64(0x55b5d38ae193bb81) 250 | , I64(0x693ae2d0a18b04b8), I64(0x5c48b4ecadd5335f) 251 | , I64(0xfd743b194916a1ca), I64(0x2577018134be98c4) 252 | , I64(0xe77987e83c54a4ad), I64(0x28e11014da33e1b9) 253 | , I64(0x270cc59e226aa213), I64(0x71495f756d1a5f60) 254 | , I64(0x9be853fb60afef77), I64(0xadc786a7f7443dbf) 255 | , I64(0x0904456173b29a82), I64(0x58bc7a66c232bd5e) 256 | , I64(0xf306558c673ac8b2), I64(0x41f639c6b6c9772a) 257 | , I64(0x216defe99fda35da), I64(0x11640cc71c7be615) 258 | , I64(0x93c43694565c5527), I64(0xea038e6246777839) 259 | , I64(0xf9abf3ce5a3e2469), I64(0x741e768d0fd312d2) 260 | , I64(0x0144b883ced652c6), I64(0xc20b5a5ba33f8552) 261 | , I64(0x1ae69633c3435a9d), I64(0x97a28ca4088cfdec) 262 | , I64(0x8824a43c1e96f420), I64(0x37612fa66eeea746) 263 | , I64(0x6b4cb165f9cf0e5a), I64(0x43aa1c06a0abfb4a) 264 | , I64(0x7f4dc26ff162796b), I64(0x6cbacc8e54ed9b0f) 265 | , I64(0xa6b7ffefd2bb253e), I64(0x2e25bc95b0a29d4f) 266 | , I64(0x86d6a58bdef1388c), I64(0xded74ac576b6f054) 267 | , I64(0x8030bdbc2b45805d), I64(0x3c81af70e94d9289) 268 | , I64(0x3eff6dda9e3100db), I64(0xb38dc39fdfcc8847) 269 | , I64(0x123885528d17b87e), I64(0xf2da0ed240b1b642) 270 | , I64(0x44cefadcd54bf9a9), I64(0x1312200e433c7ee6) 271 | , I64(0x9ffcc84f3a78c748), I64(0xf0cd1f72248576bb) 272 | , I64(0xec6974053638cfe4), I64(0x2ba7b67c0cec4e4c) 273 | , I64(0xac2f4df3e5ce32ed), I64(0xcb33d14326ea4c11) 274 | , I64(0xa4e9044cc77e58bc), I64(0x5f513293d934fcef) 275 | , I64(0x5dc9645506e55444), I64(0x50de418f317de40a) 276 | , I64(0x388cb31a69dde259), I64(0x2db4a83455820a86) 277 | , I64(0x9010a91e84711ae9), I64(0x4df7f0b7b1498371) 278 | , I64(0xd62a2eabc0977179), I64(0x22fac097aa8d5c0e) 279 | }, 280 | { 281 | I64(0xf49fcc2ff1daf39b), I64(0x487fd5c66ff29281) 282 | , I64(0xe8a30667fcdca83f), I64(0x2c9b4be3d2fcce63) 283 | , I64(0xda3ff74b93fbbbc2), I64(0x2fa165d2fe70ba66) 284 | , I64(0xa103e279970e93d4), I64(0xbecdec77b0e45e71) 285 | , I64(0xcfb41e723985e497), I64(0xb70aaa025ef75017) 286 | , I64(0xd42309f03840b8e0), I64(0x8efc1ad035898579) 287 | , I64(0x96c6920be2b2abc5), I64(0x66af4163375a9172) 288 | , I64(0x2174abdcca7127fb), I64(0xb33ccea64a72ff41) 289 | , I64(0xf04a4933083066a5), I64(0x8d970acdd7289af5) 290 | , I64(0x8f96e8e031c8c25e), I64(0xf3fec02276875d47) 291 | , I64(0xec7bf310056190dd), I64(0xf5adb0aebb0f1491) 292 | , I64(0x9b50f8850fd58892), I64(0x4975488358b74de8) 293 | , I64(0xa3354ff691531c61), I64(0x0702bbe481d2c6ee) 294 | , I64(0x89fb24057deded98), I64(0xac3075138596e902) 295 | , I64(0x1d2d3580172772ed), I64(0xeb738fc28e6bc30d) 296 | , I64(0x5854ef8f63044326), I64(0x9e5c52325add3bbe) 297 | , I64(0x90aa53cf325c4623), I64(0xc1d24d51349dd067) 298 | , I64(0x2051cfeea69ea624), I64(0x13220f0a862e7e4f) 299 | , I64(0xce39399404e04864), I64(0xd9c42ca47086fcb7) 300 | , I64(0x685ad2238a03e7cc), I64(0x066484b2ab2ff1db) 301 | , I64(0xfe9d5d70efbf79ec), I64(0x5b13b9dd9c481854) 302 | , I64(0x15f0d475ed1509ad), I64(0x0bebcd060ec79851) 303 | , I64(0xd58c6791183ab7f8), I64(0xd1187c5052f3eee4) 304 | , I64(0xc95d1192e54e82ff), I64(0x86eea14cb9ac6ca2) 305 | , I64(0x3485beb153677d5d), I64(0xdd191d781f8c492a) 306 | , I64(0xf60866baa784ebf9), I64(0x518f643ba2d08c74) 307 | , I64(0x8852e956e1087c22), I64(0xa768cb8dc410ae8d) 308 | , I64(0x38047726bfec8e1a), I64(0xa67738b4cd3b45aa) 309 | , I64(0xad16691cec0dde19), I64(0xc6d4319380462e07) 310 | , I64(0xc5a5876d0ba61938), I64(0x16b9fa1fa58fd840) 311 | , I64(0x188ab1173ca74f18), I64(0xabda2f98c99c021f) 312 | , I64(0x3e0580ab134ae816), I64(0x5f3b05b773645abb) 313 | , I64(0x2501a2be5575f2f6), I64(0x1b2f74004e7e8ba9) 314 | , I64(0x1cd7580371e8d953), I64(0x7f6ed89562764e30) 315 | , I64(0xb15926ff596f003d), I64(0x9f65293da8c5d6b9) 316 | , I64(0x6ecef04dd690f84c), I64(0x4782275fff33af88) 317 | , I64(0xe41433083f820801), I64(0xfd0dfe409a1af9b5) 318 | , I64(0x4325a3342cdb396b), I64(0x8ae77e62b301b252) 319 | , I64(0xc36f9e9f6655615a), I64(0x85455a2d92d32c09) 320 | , I64(0xf2c7dea949477485), I64(0x63cfb4c133a39eba) 321 | , I64(0x83b040cc6ebc5462), I64(0x3b9454c8fdb326b0) 322 | , I64(0x56f56a9e87ffd78c), I64(0x2dc2940d99f42bc6) 323 | , I64(0x98f7df096b096e2d), I64(0x19a6e01e3ad852bf) 324 | , I64(0x42a99ccbdbd4b40b), I64(0xa59998af45e9c559) 325 | , I64(0x366295e807d93186), I64(0x6b48181bfaa1f773) 326 | , I64(0x1fec57e2157a0a1d), I64(0x4667446af6201ad5) 327 | , I64(0xe615ebcacfb0f075), I64(0xb8f31f4f68290778) 328 | , I64(0x22713ed6ce22d11e), I64(0x3057c1a72ec3c93b) 329 | , I64(0xcb46acc37c3f1f2f), I64(0xdbb893fd02aaf50e) 330 | , I64(0x331fd92e600b9fcf), I64(0xa498f96148ea3ad6) 331 | , I64(0xa8d8426e8b6a83ea), I64(0xa089b274b7735cdc) 332 | , I64(0x87f6b3731e524a11), I64(0x118808e5cbc96749) 333 | , I64(0x9906e4c7b19bd394), I64(0xafed7f7e9b24a20c) 334 | , I64(0x6509eadeeb3644a7), I64(0x6c1ef1d3e8ef0ede) 335 | , I64(0xb9c97d43e9798fb4), I64(0xa2f2d784740c28a3) 336 | , I64(0x7b8496476197566f), I64(0x7a5be3e6b65f069d) 337 | , I64(0xf96330ed78be6f10), I64(0xeee60de77a076a15) 338 | , I64(0x2b4bee4aa08b9bd0), I64(0x6a56a63ec7b8894e) 339 | , I64(0x02121359ba34fef4), I64(0x4cbf99f8283703fc) 340 | , I64(0x398071350caf30c8), I64(0xd0a77a89f017687a) 341 | , I64(0xf1c1a9eb9e423569), I64(0x8c7976282dee8199) 342 | , I64(0x5d1737a5dd1f7abd), I64(0x4f53433c09a9fa80) 343 | , I64(0xfa8b0c53df7ca1d9), I64(0x3fd9dcbc886ccb77) 344 | , I64(0xc040917ca91b4720), I64(0x7dd00142f9d1dcdf) 345 | , I64(0x8476fc1d4f387b58), I64(0x23f8e7c5f3316503) 346 | , I64(0x032a2244e7e37339), I64(0x5c87a5d750f5a74b) 347 | , I64(0x082b4cc43698992e), I64(0xdf917becb858f63c) 348 | , I64(0x3270b8fc5bf86dda), I64(0x10ae72bb29b5dd76) 349 | , I64(0x576ac94e7700362b), I64(0x1ad112dac61efb8f) 350 | , I64(0x691bc30ec5faa427), I64(0xff246311cc327143) 351 | , I64(0x3142368e30e53206), I64(0x71380e31e02ca396) 352 | , I64(0x958d5c960aad76f1), I64(0xf8d6f430c16da536) 353 | , I64(0xc8ffd13f1be7e1d2), I64(0x7578ae66004ddbe1) 354 | , I64(0x05833f01067be646), I64(0xbb34b5ad3bfe586d) 355 | , I64(0x095f34c9a12b97f0), I64(0x247ab64525d60ca8) 356 | , I64(0xdcdbc6f3017477d1), I64(0x4a2e14d4decad24d) 357 | , I64(0xbdb5e6d9be0a1eeb), I64(0x2a7e70f7794301ab) 358 | , I64(0xdef42d8a270540fd), I64(0x01078ec0a34c22c1) 359 | , I64(0xe5de511af4c16387), I64(0x7ebb3a52bd9a330a) 360 | , I64(0x77697857aa7d6435), I64(0x004e831603ae4c32) 361 | , I64(0xe7a21020ad78e312), I64(0x9d41a70c6ab420f2) 362 | , I64(0x28e06c18ea1141e6), I64(0xd2b28cbd984f6b28) 363 | , I64(0x26b75f6c446e9d83), I64(0xba47568c4d418d7f) 364 | , I64(0xd80badbfe6183d8e), I64(0x0e206d7f5f166044) 365 | , I64(0xe258a43911cbca3e), I64(0x723a1746b21dc0bc) 366 | , I64(0xc7caa854f5d7cdd3), I64(0x7cac32883d261d9c) 367 | , I64(0x7690c26423ba942c), I64(0x17e55524478042b8) 368 | , I64(0xe0be477656a2389f), I64(0x4d289b5e67ab2da0) 369 | , I64(0x44862b9c8fbbfd31), I64(0xb47cc8049d141365) 370 | , I64(0x822c1b362b91c793), I64(0x4eb14655fb13dfd8) 371 | , I64(0x1ecbba0714e2a97b), I64(0x6143459d5cde5f14) 372 | , I64(0x53a8fbf1d5f0ac89), I64(0x97ea04d81c5e5b00) 373 | , I64(0x622181a8d4fdb3f3), I64(0xe9bcd341572a1208) 374 | , I64(0x1411258643cce58a), I64(0x9144c5fea4c6e0a4) 375 | , I64(0x0d33d06565cf620f), I64(0x54a48d489f219ca1) 376 | , I64(0xc43e5eac6d63c821), I64(0xa9728b3a72770daf) 377 | , I64(0xd7934e7b20df87ef), I64(0xe35503b61a3e86e5) 378 | , I64(0xcae321fbc819d504), I64(0x129a50b3ac60bfa6) 379 | , I64(0xcd5e68ea7e9fb6c3), I64(0xb01c90199483b1c7) 380 | , I64(0x3de93cd5c295376c), I64(0xaed52edf2ab9ad13) 381 | , I64(0x2e60f512c0a07884), I64(0xbc3d86a3e36210c9) 382 | , I64(0x35269d9b163951ce), I64(0x0c7d6e2ad0cdb5fa) 383 | , I64(0x59e86297d87f5733), I64(0x298ef221898db0e7) 384 | , I64(0x55000029d1a5aa7e), I64(0x8bc08ae1b5061b45) 385 | , I64(0xc2c31c2b6c92703a), I64(0x94cc596baf25ef42) 386 | , I64(0x0a1d73db22540456), I64(0x04b6a0f9d9c4179a) 387 | , I64(0xeffdafa2ae3d3c60), I64(0xf7c8075bb49496c4) 388 | , I64(0x9cc5c7141d1cd4e3), I64(0x78bd1638218e5534) 389 | , I64(0xb2f11568f850246a), I64(0xedfabcfa9502bc29) 390 | , I64(0x796ce5f2da23051b), I64(0xaae128b0dc93537c) 391 | , I64(0x3a493da0ee4b29ae), I64(0xb5df6b2c416895d7) 392 | , I64(0xfcabbd25122d7f37), I64(0x70810b58105dc4b1) 393 | , I64(0xe10fdd37f7882a90), I64(0x524dcab5518a3f5c) 394 | , I64(0x3c9e85878451255b), I64(0x4029828119bd34e2) 395 | , I64(0x74a05b6f5d3ceccb), I64(0xb610021542e13eca) 396 | , I64(0x0ff979d12f59e2ac), I64(0x6037da27e4f9cc50) 397 | , I64(0x5e92975a0df1847d), I64(0xd66de190d3e623fe) 398 | , I64(0x5032d6b87b568048), I64(0x9a36b7ce8235216e) 399 | , I64(0x80272a7a24f64b4a), I64(0x93efed8b8c6916f7) 400 | , I64(0x37ddbff44cce1555), I64(0x4b95db5d4b99bd25) 401 | , I64(0x92d3fda169812fc0), I64(0xfb1a4a9a90660bb6) 402 | , I64(0x730c196946a4b9b2), I64(0x81e289aa7f49da68) 403 | , I64(0x64669a0f83b1a05f), I64(0x27b3ff7d9644f48b) 404 | , I64(0xcc6b615c8db675b3), I64(0x674f20b9bcebbe95) 405 | , I64(0x6f31238275655982), I64(0x5ae488713e45cf05) 406 | , I64(0xbf619f9954c21157), I64(0xeabac46040a8eae9) 407 | , I64(0x454c6fe9f2c0c1cd), I64(0x419cf6496412691c) 408 | , I64(0xd3dc3bef265b0f70), I64(0x6d0e60f5c3578a9e) 409 | }, 410 | { 411 | I64(0x5b0e608526323c55), I64(0x1a46c1a9fa1b59f5) 412 | , I64(0xa9e245a17c4c8ffa), I64(0x65ca5159db2955d7) 413 | , I64(0x05db0a76ce35afc2), I64(0x81eac77ea9113d45) 414 | , I64(0x528ef88ab6ac0a0d), I64(0xa09ea253597be3ff) 415 | , I64(0x430ddfb3ac48cd56), I64(0xc4b3a67af45ce46f) 416 | , I64(0x4ececfd8fbe2d05e), I64(0x3ef56f10b39935f0) 417 | , I64(0x0b22d6829cd619c6), I64(0x17fd460a74df2069) 418 | , I64(0x6cf8cc8e8510ed40), I64(0xd6c824bf3a6ecaa7) 419 | , I64(0x61243d581a817049), I64(0x048bacb6bbc163a2) 420 | , I64(0xd9a38ac27d44cc32), I64(0x7fddff5baaf410ab) 421 | , I64(0xad6d495aa804824b), I64(0xe1a6a74f2d8c9f94) 422 | , I64(0xd4f7851235dee8e3), I64(0xfd4b7f886540d893) 423 | , I64(0x247c20042aa4bfda), I64(0x096ea1c517d1327c) 424 | , I64(0xd56966b4361a6685), I64(0x277da5c31221057d) 425 | , I64(0x94d59893a43acff7), I64(0x64f0c51ccdc02281) 426 | , I64(0x3d33bcc4ff6189db), I64(0xe005cb184ce66af1) 427 | , I64(0xff5ccd1d1db99bea), I64(0xb0b854a7fe42980f) 428 | , I64(0x7bd46a6a718d4b9f), I64(0xd10fa8cc22a5fd8c) 429 | , I64(0xd31484952be4bd31), I64(0xc7fa975fcb243847) 430 | , I64(0x4886ed1e5846c407), I64(0x28cddb791eb70b04) 431 | , I64(0xc2b00be2f573417f), I64(0x5c9590452180f877) 432 | , I64(0x7a6bddfff370eb00), I64(0xce509e38d6d9d6a4) 433 | , I64(0xebeb0f00647fa702), I64(0x1dcc06cf76606f06) 434 | , I64(0xe4d9f28ba286ff0a), I64(0xd85a305dc918c262) 435 | , I64(0x475b1d8732225f54), I64(0x2d4fb51668ccb5fe) 436 | , I64(0xa679b9d9d72bba20), I64(0x53841c0d912d43a5) 437 | , I64(0x3b7eaa48bf12a4e8), I64(0x781e0e47f22f1ddf) 438 | , I64(0xeff20ce60ab50973), I64(0x20d261d19dffb742) 439 | , I64(0x16a12b03062a2e39), I64(0x1960eb2239650495) 440 | , I64(0x251c16fed50eb8b8), I64(0x9ac0c330f826016e) 441 | , I64(0xed152665953e7671), I64(0x02d63194a6369570) 442 | , I64(0x5074f08394b1c987), I64(0x70ba598c90b25ce1) 443 | , I64(0x794a15810b9742f6), I64(0x0d5925e9fcaf8c6c) 444 | , I64(0x3067716cd868744e), I64(0x910ab077e8d7731b) 445 | , I64(0x6a61bbdb5ac42f61), I64(0x93513efbf0851567) 446 | , I64(0xf494724b9e83e9d5), I64(0xe887e1985c09648d) 447 | , I64(0x34b1d3c675370cfd), I64(0xdc35e433bc0d255d) 448 | , I64(0xd0aab84234131be0), I64(0x08042a50b48b7eaf) 449 | , I64(0x9997c4ee44a3ab35), I64(0x829a7b49201799d0) 450 | , I64(0x263b8307b7c54441), I64(0x752f95f4fd6a6ca6) 451 | , I64(0x927217402c08c6e5), I64(0x2a8ab754a795d9ee) 452 | , I64(0xa442f7552f72943d), I64(0x2c31334e19781208) 453 | , I64(0x4fa98d7ceaee6291), I64(0x55c3862f665db309) 454 | , I64(0xbd0610175d53b1f3), I64(0x46fe6cb840413f27) 455 | , I64(0x3fe03792df0cfa59), I64(0xcfe700372eb85e8f) 456 | , I64(0xa7be29e7adbce118), I64(0xe544ee5cde8431dd) 457 | , I64(0x8a781b1b41f1873e), I64(0xa5c94c78a0d2f0e7) 458 | , I64(0x39412e2877b60728), I64(0xa1265ef3afc9a62c) 459 | , I64(0xbcc2770c6a2506c5), I64(0x3ab66dd5dce1ce12) 460 | , I64(0xe65499d04a675b37), I64(0x7d8f523481bfd216) 461 | , I64(0x0f6f64fcec15f389), I64(0x74efbe618b5b13c8) 462 | , I64(0xacdc82b714273e1d), I64(0xdd40bfe003199d17) 463 | , I64(0x37e99257e7e061f8), I64(0xfa52626904775aaa) 464 | , I64(0x8bbbf63a463d56f9), I64(0xf0013f1543a26e64) 465 | , I64(0xa8307e9f879ec898), I64(0xcc4c27a4150177cc) 466 | , I64(0x1b432f2cca1d3348), I64(0xde1d1f8f9f6fa013) 467 | , I64(0x606602a047a7ddd6), I64(0xd237ab64cc1cb2c7) 468 | , I64(0x9b938e7225fcd1d3), I64(0xec4e03708e0ff476) 469 | , I64(0xfeb2fbda3d03c12d), I64(0xae0bced2ee43889a) 470 | , I64(0x22cb8923ebfb4f43), I64(0x69360d013cf7396d) 471 | , I64(0x855e3602d2d4e022), I64(0x073805bad01f784c) 472 | , I64(0x33e17a133852f546), I64(0xdf4874058ac7b638) 473 | , I64(0xba92b29c678aa14a), I64(0x0ce89fc76cfaadcd) 474 | , I64(0x5f9d4e0908339e34), I64(0xf1afe9291f5923b9) 475 | , I64(0x6e3480f60f4a265f), I64(0xeebf3a2ab29b841c) 476 | , I64(0xe21938a88f91b4ad), I64(0x57dfeff845c6d3c3) 477 | , I64(0x2f006b0bf62caaf2), I64(0x62f479ef6f75ee78) 478 | , I64(0x11a55ad41c8916a9), I64(0xf229d29084fed453) 479 | , I64(0x42f1c27b16b000e6), I64(0x2b1f76749823c074) 480 | , I64(0x4b76eca3c2745360), I64(0x8c98f463b91691bd) 481 | , I64(0x14bcc93cf1ade66a), I64(0x8885213e6d458397) 482 | , I64(0x8e177df0274d4711), I64(0xb49b73b5503f2951) 483 | , I64(0x10168168c3f96b6b), I64(0x0e3d963b63cab0ae) 484 | , I64(0x8dfc4b5655a1db14), I64(0xf789f1356e14de5c) 485 | , I64(0x683e68af4e51dac1), I64(0xc9a84f9d8d4b0fd9) 486 | , I64(0x3691e03f52a0f9d1), I64(0x5ed86e46e1878e80) 487 | , I64(0x3c711a0e99d07150), I64(0x5a0865b20c4e9310) 488 | , I64(0x56fbfc1fe4f0682e), I64(0xea8d5de3105edf9b) 489 | , I64(0x71abfdb12379187a), I64(0x2eb99de1bee77b9c) 490 | , I64(0x21ecc0ea33cf4523), I64(0x59a4d7521805c7a1) 491 | , I64(0x3896f5eb56ae7c72), I64(0xaa638f3db18f75dc) 492 | , I64(0x9f39358dabe9808e), I64(0xb7defa91c00b72ac) 493 | , I64(0x6b5541fd62492d92), I64(0x6dc6dee8f92e4d5b) 494 | , I64(0x353f57abc4beea7e), I64(0x735769d6da5690ce) 495 | , I64(0x0a234aa642391484), I64(0xf6f9508028f80d9d) 496 | , I64(0xb8e319a27ab3f215), I64(0x31ad9c1151341a4d) 497 | , I64(0x773c22a57bef5805), I64(0x45c7561a07968633) 498 | , I64(0xf913da9e249dbe36), I64(0xda652d9b78a64c68) 499 | , I64(0x4c27a97f3bc334ef), I64(0x76621220e66b17f4) 500 | , I64(0x967743899acd7d0b), I64(0xf3ee5bcae0ed6782) 501 | , I64(0x409f753600c879fc), I64(0x06d09a39b5926db6) 502 | , I64(0x6f83aeb0317ac588), I64(0x01e6ca4a86381f21) 503 | , I64(0x66ff3462d19f3025), I64(0x72207c24ddfd3bfb) 504 | , I64(0x4af6b6d3e2ece2eb), I64(0x9c994dbec7ea08de) 505 | , I64(0x49ace597b09a8bc4), I64(0xb38c4766cf0797ba) 506 | , I64(0x131b9373c57c2a75), I64(0xb1822cce61931e58) 507 | , I64(0x9d7555b909ba1c0c), I64(0x127fafdd937d11d2) 508 | , I64(0x29da3badc66d92e4), I64(0xa2c1d57154c2ecbc) 509 | , I64(0x58c5134d82f6fe24), I64(0x1c3ae3515b62274f) 510 | , I64(0xe907c82e01cb8126), I64(0xf8ed091913e37fcb) 511 | , I64(0x3249d8f9c80046c9), I64(0x80cf9bede388fb63) 512 | , I64(0x1881539a116cf19e), I64(0x5103f3f76bd52457) 513 | , I64(0x15b7e6f5ae47f7a8), I64(0xdbd7c6ded47e9ccf) 514 | , I64(0x44e55c410228bb1a), I64(0xb647d4255edb4e99) 515 | , I64(0x5d11882bb8aafc30), I64(0xf5098bbb29d3212a) 516 | , I64(0x8fb5ea14e90296b3), I64(0x677b942157dd025a) 517 | , I64(0xfb58e7c0a390acb5), I64(0x89d3674c83bd4a01) 518 | , I64(0x9e2da4df4bf3b93b), I64(0xfcc41e328cab4829) 519 | , I64(0x03f38c96ba582c52), I64(0xcad1bdbd7fd85db2) 520 | , I64(0xbbb442c16082ae83), I64(0xb95fe86ba5da9ab0) 521 | , I64(0xb22e04673771a93f), I64(0x845358c9493152d8) 522 | , I64(0xbe2a488697b4541e), I64(0x95a2dc2dd38e6966) 523 | , I64(0xc02c11ac923c852b), I64(0x2388b1990df2a87b) 524 | , I64(0x7c8008fa1b4f37be), I64(0x1f70d0c84d54e503) 525 | , I64(0x5490adec7ece57d4), I64(0x002b3c27d9063a3a) 526 | , I64(0x7eaea3848030a2bf), I64(0xc602326ded2003c0) 527 | , I64(0x83a7287d69a94086), I64(0xc57a5fcb30f57a8a) 528 | , I64(0xb56844e479ebe779), I64(0xa373b40f05dcbce9) 529 | , I64(0xd71a786e88570ee2), I64(0x879cbacdbde8f6a0) 530 | , I64(0x976ad1bcc164a32f), I64(0xab21e25e9666d78b) 531 | , I64(0x901063aae5e5c33c), I64(0x9818b34448698d90) 532 | , I64(0xe36487ae3e1e8abb), I64(0xafbdf931893bdcb4) 533 | , I64(0x6345a0dc5fbbd519), I64(0x8628fe269b9465ca) 534 | , I64(0x1e5d01603f9c51ec), I64(0x4de44006a15049b7) 535 | , I64(0xbf6c70e5f776cbb1), I64(0x411218f2ef552bed) 536 | , I64(0xcb0c0708705a36a3), I64(0xe74d14754f986044) 537 | , I64(0xcd56d9430ea8280e), I64(0xc12591d7535f5065) 538 | , I64(0xc83223f1720aef96), I64(0xc3a0396f7363a51f) 539 | } 540 | }; --------------------------------------------------------------------------------