Parcourir la source

Got ElGamal and AES handshake working

master
thajohns il y a 2 ans
Parent
révision
3990c4578d
  1. 12
      aes.c
  2. 1
      aes.h
  3. 20
      client.c
  4. 89
      comm.c
  5. 4
      comm.h
  6. 2
      randsource.c
  7. 43
      server.c
  8. 11
      sgprime.c

12
aes.c

@ -136,7 +136,7 @@ void initializeSBox()
static uint32_t wordSBox(uint32_t word)
{
return
(sbox[word]) |
(sbox[(uint8_t) word]) |
(sbox[(uint8_t) (word >> 8)] << 8) |
(sbox[(uint8_t) (word >> 16)] << 16) |
(sbox[(uint8_t) (word >> 24)] << 24);
@ -227,7 +227,7 @@ void AESRound(uint32_t state[4], uint32_t key[60])
}
}
void dataToState(char data[16], uint32_t state[4]);
void dataToState(char data[16], uint32_t state[4])
{
int ii;
for (ii = 0; ii < 4; ii++)
@ -252,6 +252,14 @@ void stateToData(uint32_t state[4], char data[16])
}
}
void AESRound_data(char data[16], uint32_t key[60])
{
uint32_t state[4];
dataToState(data, state);
AESRound(state, key);
stateToData(state, data);
}
//int main()
//{

1
aes.h

@ -8,5 +8,6 @@ void expandKey(uint32_t short_key[8], uint32_t expanded_key[60]);
void AESRound(uint32_t state[4], uint32_t key[60]);
void dataToState(char data[16], uint32_t state[4]);
void stateToData(uint32_t state[4], char data[16]);
void AESRound_data(char data[16], uint32_t key[60]);
#endif

20
client.c

@ -1,10 +1,28 @@
#include <stdio.h>
#include <errno.h>
#include "comm.h"
#include "aes.h"
int main()
{
struct session sess;
initializeSBox();
sess_init(&sess);
if (do_resolve("127.0.0.1", NULL, &sess.params))
{
perror("could not open socket");
return 1;
}
if (do_connect(&sess))
{
perror("could not connect");
return 1;
}
do_resolve("127.0.0.1", NULL, &sess.params);
do_unresolve(sess.params);
sess_destroy(&sess);
}

89
comm.c

@ -15,7 +15,39 @@
#include <string.h>
#include <errno.h>
size_t eight = 8;
#define RAND_SIZE 512
void sess_init(struct session *sess)
{
mpz_t seed;
mpz_init(seed);
char *randbuff = malloc(RAND_SIZE);
gmp_randinit_default(sess->rs);
fill_random(randbuff, RAND_SIZE);
mpz_import(seed, RAND_SIZE, 1, 1, 0, 0, randbuff);
gmp_randseed(sess->rs, seed);
free(randbuff);
mpz_init(sess->eg.m);
mpz_init(sess->eg.g);
mpz_init(sess->eg.p);
mpz_init(sess->eg.x);
mpz_clear(seed);
}
void sess_destroy(struct session *sess)
{
mpz_clear(sess->eg.m);
mpz_clear(sess->eg.g);
mpz_clear(sess->eg.p);
mpz_clear(sess->eg.x);
gmp_randclear(sess->rs);
}
int do_resolve(char *address, char *portstr, struct sock_params *params)
{
@ -51,12 +83,14 @@ int do_resolve(char *address, char *portstr, struct sock_params *params)
{
return err;
}
((struct sockaddr_in*) ai->ai_addr)->sin_port = htons(port);
} else if (1 == sscanf(portstr, "%hu", &port))
{
if ((err = getaddrinfo(address, NULL, &hints, &ai)))
{
return err;
}
((struct sockaddr_in*) ai->ai_addr)->sin_port = htons(port);
} else
{
if ((err = getaddrinfo(address, portstr, &hints, &ai)))
@ -87,21 +121,21 @@ int send_num(mpz_t n, struct session *sess)
{
size_t nbytes;
void *buf = mpz_export(NULL, &nbytes, 1, 1, 1, 0, n);
if (nbytes > (1 << 16))
if (nbytes >= (1 << 16))
{
free(buf);
return -1;
}
uint16_t size = htons((uint16_t) nbytes);
write(sess->params.sock, &size, 2);
write(sess->params.sock, buf, size);
write(sess->params.sock, buf, nbytes);
free(buf);
return 0;
}
int recv_num(mpz_t n, struct session *sess)
{
uint16_t size;
uint16_t size = 0;
read(sess->params.sock, &size, 2);
size_t nbytes = ntohs(size);
void *buf = malloc(nbytes);
@ -111,6 +145,27 @@ int recv_num(mpz_t n, struct session *sess)
return 0;
}
int send_data(char data[16], struct session *sess)
{
write(sess->params.sock, data, 16);
return 0;
}
int recv_data(char data[16], struct session *sess)
{
read(sess->params.sock, data, 16);
return 0;
}
void initial_aes_handshake(struct session *sess)
{
fill_random(sess->last_sent_enc, 16);
send_data(sess->last_sent_enc, sess);
AESRound_data(sess->last_sent_enc, sess->key);
recv_data(sess->last_recv_enc, sess);
AESRound_data(sess->last_recv_enc, sess->key);
}
int do_connect(struct session *sess)
{
int en = connect(sess->params.sock, sess->params.addr, sess->params.addrlen);
@ -129,17 +184,22 @@ int do_connect(struct session *sess)
mpz_init(k);
mpz_init(h);
mpz_urandomm(a, sess->rs, sess->eg.m);
mpz_import(k, 8, 1, 4, 1, 0, rshort_key);
mpz_mod(k, k, sess->eg.m);
mpz_export(short_key, &eight, 1, 4, 1, 0, k);
size_t nbytes;
void *buf = mpz_export(NULL, &nbytes, -1, 4, 1, 0, k);
memcpy(short_key, buf, 32);
free(buf);
expandKey(short_key, sess->key);
mpz_powm(h, sess->eg.g, a, sess->eg.m);
mpz_powm(a, sess->eg.p, a, sess->eg.m);
mpz_mul(a, k, a);
mpz_mod(a, a, sess->eg.m);
expandKey(short_key, sess->key);
send_num(h, sess);
send_num(a, sess);
@ -147,6 +207,8 @@ int do_connect(struct session *sess)
mpz_clear(k);
mpz_clear(h);
initial_aes_handshake(sess);
return 0;
}
@ -163,6 +225,8 @@ int do_receive(struct session *sess)
return errno;
close(sess->params.sock);
sess->params.sock = en;
struct linger linger = {0, 0};
setsockopt(sess->params.sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(struct linger));
uint32_t short_key[8] = {0};
@ -178,18 +242,23 @@ int do_receive(struct session *sess)
recv_num(h, sess);
recv_num(a, sess);
mpz_neg(f, sess->eg.m);
mpz_powm(f, h, sess->eg.x, f);
mpz_neg(f, sess->eg.x);
mpz_powm(f, h, f, sess->eg.m);
mpz_mul(a, a, f);
mpz_mod(a, a, sess->eg.m);
mpz_export(short_key, &eight, 1, 4, 1, 0, a);
size_t nbytes;
void *buf = mpz_export(NULL, &nbytes, -1, 4, 1, 0, a);
memcpy(short_key, buf, 32);
free(buf);
expandKey(short_key, sess->key);
mpz_clear(h);
mpz_clear(f);
mpz_clear(a);
initial_aes_handshake(sess);
return 0;
}

4
comm.h

@ -28,8 +28,12 @@ struct session
struct sock_params params;
struct elgamal eg;
gmp_randstate_t rs;
char last_sent_enc[16];
char last_recv_enc[16];
};
void sess_init(struct session *sess);
void sess_destroy(struct session *sess);
int do_resolve(char *address, char *portstr, struct sock_params *params);
void do_unresolve(struct sock_params params);
int do_connect(struct session *sess);

2
randsource.c

@ -4,6 +4,8 @@
#include <stdlib.h>
#include <errno.h>
// This function must return 0 on success, nonzero otherwise. Its job is to
// fill the buffer of the size given witih randomness.
int fill_random(void *buf, int size)
{
FILE *random = fopen("/dev/urandom", "r");

43
server.c

@ -0,0 +1,43 @@
#include <stdio.h>
#include <errno.h>
#include "comm.h"
#include "aes.h"
int main()
{
struct session sess;
initializeSBox();
sess_init(&sess);
FILE *keyf = fopen("key.out", "r");
if (keyf == NULL)
{
perror("could not open key file");
return 1;
}
if (4 != gmp_fscanf(keyf, "m=%Zd\ng=%Zd\nx=%Zd\np=%Zd\n", sess.eg.m, sess.eg.g, sess.eg.x, sess.eg.p))
{
fprintf(stderr, "not a valid key file");
return 2;
}
fclose(keyf);
if (do_resolve("127.0.0.1", NULL, &sess.params))
{
perror("could not open socket");
return 1;
}
if (do_receive(&sess))
{
perror("could not accept");
return 1;
}
do_unresolve(sess.params);
sess_destroy(&sess);
}

11
sgprime.c

@ -1,5 +1,14 @@
#define PRIMORIAL_CAP_CAP 10000000
// This value is tuned for generating large keys, or small keys many times. Higher values see
// diminishing returns in efficiency (and though I cannot prove it, I believe that there is no
// upper bound on the efficiency attainable by setting it higher, but it just isn't worth it.)
// The larger this number, the longer build_sieve() will take (and thus make_difflist()). Also,
// larger values of this number will use more memory. I wouldn't recommend setting it any higher,
// but for generating small numbers of small keys, setting it lower is a good idea.
// Another thing I forgot: Larger values will tend to make multithreaded searches where the
// number of threads is not a multiple of many small primes whose primorial is less then this
// number take much longer and use more memory.
#define PRIMORIAL_CAP_CAP 1000000
#include <stdlib.h>
#include <stdio.h>

Chargement…
Annuler
Enregistrer