#include "lib/aes.h" #include "lib/md5.h" #include #include #include #include #include "encrypt.h" #include "common.h" #include "log.h" //static uint64_t seq=1; static int8_t zero_iv[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0};//this prog use zero iv,you should make sure first block of data contains a random/nonce data /**** * security of zero_iv + nonce first data block * https://crypto.stackexchange.com/questions/5421/using-cbc-with-a-fixed-iv-and-a-random-first-plaintext-block ****/ char key[16];//generated from key_string by md5. /* TODO Change md5 to HMAC-md5 if necessary.Change padding to PKCS#7 style if necessary. Need someone with cryptography knowledge to help review the encryption method. Change them if necessary(I can do this by myself,if it turns out to be necessary). github issue: https://github.com/wangyu-/udp2raw-tunnel/issues/17 */ unordered_map auth_mode_tostring = {{auth_none, "none"}, {auth_md5, "md5"}, {auth_crc32, "crc32"},{auth_simple,"simple"}}; unordered_map cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"}}; auth_mode_t auth_mode=auth_md5; cipher_mode_t cipher_mode=cipher_aes128cbc; /* * this function comes from http://www.hackersdelight.org/hdcodetxt/crc.c.txt */ unsigned int crc32h(unsigned char *message,int len) { int i, crc; unsigned int byte, c; const unsigned int g0 = 0xEDB88320, g1 = g0>>1, g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5, g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1; i = 0; crc = 0xFFFFFFFF; while (i!=len) { // Get next byte. byte = message[i]; crc = crc ^ byte; c = ((crc<<31>>31) & g7) ^ ((crc<<30>>31) & g6) ^ ((crc<<29>>31) & g5) ^ ((crc<<28>>31) & g4) ^ ((crc<<27>>31) & g3) ^ ((crc<<26>>31) & g2) ^ ((crc<<25>>31) & g1) ^ ((crc<<24>>31) & g0); crc = ((unsigned)crc >> 8) ^ c; i = i + 1; } return ~crc; } /* void sum(const unsigned char *data,int len,unsigned char* res) { memset(res,0,sizeof(int)); for(int i=0,j=0;ipadding_num) return -1; data_len-=(uint8_t)data[data_len-1]; if(data_len<0) { return -1; } return 0; } int cipher_aes128cbc_encrypt(const char *data,char *output,int &len,char * key) { static int first_time=1; if(aes_key_optimize) { if(first_time==0) key=0; else first_time=0; } char buf[buf_len]; memcpy(buf,data,len);//TODO inefficient code /* int ori_len=len; len+=2;//length if(len%16!=0) { len= (len/16)*16+16; } //if(len>max_data_len) return -1; buf[len-2]= (unsigned char)( (uint16_t(ori_len))>>8); buf[len-1]=(unsigned char)( ((uint16_t(ori_len))<<8)>>8) ;*/ if(padding(buf,len,16)<0) return -1; AES_CBC_encrypt_buffer((unsigned char *)output,(unsigned char *)buf,len,(unsigned char *)key,(unsigned char *)zero_iv); return 0; } int auth_crc32_verify(const char *data,int &len) { if(lenmax_data_len) {mylog(log_warn,"len>max_data_len");return -1;} char buf[buf_len]; char buf2[buf_len]; memcpy(buf,data,len); if(auth_cal(buf,buf2,len)!=0) {mylog(log_debug,"auth_cal failed ");return -1;} if(cipher_encrypt(buf2,output,len,key) !=0) {mylog(log_debug,"cipher_encrypt failed ");return -1;} return 0; } int my_decrypt(const char *data,char *output,int &len,char * key) { if(len<0) return -1; if(len>max_data_len) {mylog(log_warn,"len>max_data_len");return -1;} if(cipher_decrypt(data,output,len,key) !=0) {mylog(log_debug,"cipher_decrypt failed \n"); return -1;} if(auth_verify(output,len)!=0) {mylog(log_debug,"auth_verify failed\n");return -1;} return 0; } int my_encrypt_pesudo_header(uint8_t *data,uint8_t *output,int &len,uint8_t * key,uint8_t *header,int hlen) { return 0; } int my_decrypt_pesudo_header(uint8_t *data,uint8_t *output,int &len,uint8_t * key,uint8_t *header,int hlen) { return 0; }