blob: a7a113b48e113972447f1cff088e6c66802f7afa [file] [log] [blame] [raw]
//#include <stdint.h>
#include "ecc.h"
#include "ecies-chacha20.h"
#include <sys/types.h>
#include "chacha20_simple.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define CHACHA20_BLOCK_BYTES 64
#define CHACHA20_NONCE_SIZE 8
ECIES_byte_t ChaCha20_nonce[CHACHA20_NONCE_SIZE] = { 1, 1, 1, 1, 1, 1, 1, 1 };
const ECIES_size_t ChaCha20_nonce_size = CHACHA20_NONCE_SIZE;
static void debug_print_bytes(const ECIES_byte_t *a, size_t len) {
unsigned int i;
for(i=0; i<len; i++) fprintf(stderr, "0x%hhx, ", a[i]);
fputc('\n', stderr);
}
static void ChaCha20_init_ctx(chacha20_ctx *ctx, const uint8_t *key) {
//uint8_t nonce[8];
/*
int fd = open("/dev/urandom", O_RDONLY);
if(fd == -1) {
perror("/dev/urandom");
exit(1);
}
int count = 0;
do {
int s = read(fd, nonce + count, sizeof nonce - count);
if(s < 0) {
if(errno == EINTR) continue;
perror("/dev/urandom");
exit(1);
}
if(!s) {
fprintf(stderr, "panic? /dev/urandom EOF??\n");
exit(1);
}
count += s;
} while(count < sizeof nonce);
close(fd);
*/
//memset(nonce, 1, sizeof nonce);
//fprintf(stderr, "ChaCha20_nonce[0] = 0x%hhx\n", ChaCha20_nonce[0]);
chacha20_setup(ctx, key, CHACHA20_KEY_BYTES, ChaCha20_nonce);
}
unsigned int ChaCha20_key_bytes() {
return CHACHA20_KEY_BYTES;
}
void ChaCha20_ctr_crypt(ECIES_byte_t *data, ECIES_size_t size, const ECIES_byte_t *key) {
fprintf(stderr, "function: ChaCha20_ctr_crypt(%p, %u, %p)\n", data, size, key);
chacha20_ctx ctx;
ChaCha20_init_ctx(&ctx, key);
/*
uint32_t ctr = 0;
int i;
ECIES_byte_t buffer[CHACHA20_BLOCK_BYTES];
while(size) {
//for(i = CHACHA20_BLOCK_BYTES / sizeof ctr - 1; i >= 0; i--) INT2CHARS(buffer + sizeof ctr * i, 0);
for(i = CHACHA20_BLOCK_BYTES - sizeof ctr; i >= 0; i -= sizeof ctr) INT2CHARS(buffer + i, ctr++);
chacha20_encrypt(&ctx, buffer, buffer, sizeof buffer);
ECIES_size_t len = MIN(sizeof buffer, size);
for(i = 0; i < len; i++) *data++ ^= buffer[i];
size -= len;
}
*/
// ChaCha20 is already a counter mode cipher
chacha20_encrypt(&ctx, data, data, size);
}
void ChaCha20_cbc_mac(ECIES_byte_t *mac, const ECIES_byte_t *data, ECIES_size_t size, const ECIES_byte_t *key) {
fprintf(stderr, "function: ChaCha20_cbc_mac(%p, %p, %u, %p)\n", mac, data, size, key);
chacha20_ctx ctx;
unsigned int i;
ChaCha20_init_ctx(&ctx, key);
// sizeof size == 4
//INT2CHARS(mac, size);
INT2CHARS(mac, 0);
INT2CHARS(mac + 4, size);
chacha20_encrypt(&ctx, mac, mac, ECIES_CHUNK_OVERHEAD);
while(size) {
//ECIES_size_t blen = MIN(CHACHA20_BLOCK_BYTES, size);
ECIES_size_t blen = MIN(ECIES_CHUNK_OVERHEAD, size);
for(i = 0; i < blen; i++) mac[i] ^= *data++;
//chacha20_encrypt(&ctx, mac, mac, CHACHA20_BLOCK_BYTES);
chacha20_encrypt(&ctx, mac, mac, ECIES_CHUNK_OVERHEAD);
size -= blen;
}
}
void ChaCha20_davies_meyer(ECIES_byte_t *out, const ECIES_byte_t *in, int ilen) {
fprintf(stderr, "function: ChaCha20_davies_meyer(%p, %p, %d)\n", out, in, ilen);
debug_print_bytes(ChaCha20_nonce, 8);
unsigned int i;
ECIES_byte_t buffer[CHACHA20_KEY_BYTES / 2];
chacha20_ctx ctx;
memset(out, 0, CHACHA20_KEY_BYTES / 2);
while(ilen--) {
ChaCha20_init_ctx(&ctx, in);
memcpy(buffer, out, sizeof buffer);
chacha20_encrypt(&ctx, buffer, buffer, sizeof buffer);
debug_print_bytes(buffer, sizeof buffer);
for(i = 0; i < sizeof buffer; i++) out[i] ^= buffer[i];
in += CHACHA20_KEY_BYTES;
}
}