Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add chacha12 and chacha20 #257

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions encrypt.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "lib/aes-common.h"
#include "lib/chacha20.h"
#include "lib/md5.h"
#include "lib/pbkdf2-sha1.h"
#include "lib/pbkdf2-sha256.h"
Expand Down Expand Up @@ -28,7 +29,7 @@ unsigned char cipher_key_decrypt[cipher_key_len + 100]; //key for aes etc.

unordered_map<int, const char *> auth_mode_tostring = {{auth_none, "none"}, {auth_md5, "md5"}, {auth_crc32, "crc32"},{auth_simple,"simple"},{auth_hmac_sha1,"hmac_sha1"},};

unordered_map<int, const char *> cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cfb,"aes128cfb"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"},};
unordered_map<int, const char *> cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cfb,"aes128cfb"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"},{cipher_chacha12,"chacha12"},{cipher_chacha20,"chacha20"},};
//TODO aes-gcm

auth_mode_t auth_mode=auth_md5;
Expand Down Expand Up @@ -324,6 +325,20 @@ int cipher_aes128cfb_encrypt(const char *data,char *output,int &len,char * key)
AES_CFB_encrypt_buffer((unsigned char *)output,(unsigned char *)buf,len,(unsigned char *)key,(unsigned char *)zero_iv);
return 0;
}
int cipher_chacha12_encrypt(const char *data,char *output,int &len,char * key)
{
ChaCha12XOR((uint8_t *) key, 1, (uint8_t *) zero_iv,
(uint8_t *) data, (uint8_t *) output, len);
//AES_CBC_encrypt_buffer((unsigned char *)output,(unsigned char *)buf,len,(unsigned char *)key,(unsigned char *)zero_iv);
return 0;
}
int cipher_chacha20_encrypt(const char *data,char *output,int &len,char * key)
{
ChaCha20XOR((uint8_t *) key, 1, (uint8_t *) zero_iv,
(uint8_t *) data, (uint8_t *) output, len);
//AES_CBC_encrypt_buffer((unsigned char *)output,(unsigned char *)buf,len,(unsigned char *)key,(unsigned char *)zero_iv);
return 0;
}
int auth_crc32_verify(const char *data,int &len)
{
if(len<int(sizeof(unsigned int)))
Expand Down Expand Up @@ -372,7 +387,19 @@ int cipher_aes128cfb_decrypt(const char *data,char *output,int &len,char * key)
//if(de_padding(output,len,16)<0) return -1;
return 0;
}

int cipher_chacha12_decrypt(const char *data,char *output,int &len,char * key)
{
ChaCha12XOR((uint8_t *) key, 1, (uint8_t *) zero_iv,
(uint8_t *) data, (uint8_t *) output, len);
return 0;
}
int cipher_chacha20_decrypt(const char *data,char *output,int &len,char * key)
{
ChaCha20XOR((uint8_t *) key, 1, (uint8_t *) zero_iv,
(uint8_t *) data, (uint8_t *) output, len);
//AES_CBC_decrypt_buffer((unsigned char *)output,(unsigned char *)data,len,(unsigned char *)key,(unsigned char *)zero_iv);
return 0;
}
int cipher_none_decrypt(const char *data,char *output,int &len,char * key)
{
memcpy(output,data,len);
Expand Down Expand Up @@ -417,6 +444,8 @@ int cipher_encrypt(const char *data,char *output,int &len,char * key)
switch(cipher_mode)
{
case cipher_aes128cbc:return cipher_aes128cbc_encrypt(data,output,len, key);
case cipher_chacha12:return cipher_chacha12_encrypt(data,output,len, key);
case cipher_chacha20:return cipher_chacha20_encrypt(data,output,len, key);
case cipher_aes128cfb:return cipher_aes128cfb_encrypt(data,output,len, key);
case cipher_xor:return cipher_xor_encrypt(data,output,len, key);
case cipher_none:return cipher_none_encrypt(data,output,len, key);
Expand All @@ -431,6 +460,8 @@ int cipher_decrypt(const char *data,char *output,int &len,char * key)
switch(cipher_mode)
{
case cipher_aes128cbc:return cipher_aes128cbc_decrypt(data,output,len, key);
case cipher_chacha12:return cipher_chacha12_decrypt(data,output,len, key);
case cipher_chacha20:return cipher_chacha20_decrypt(data,output,len, key);
case cipher_aes128cfb:return cipher_aes128cfb_decrypt(data,output,len, key);
case cipher_xor:return cipher_xor_decrypt(data,output,len, key);
case cipher_none:return cipher_none_decrypt(data,output,len, key);
Expand Down
2 changes: 1 addition & 1 deletion encrypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ unsigned short csum(const unsigned short *ptr,int nbytes) ;
enum auth_mode_t {auth_none=0,auth_md5,auth_crc32,auth_simple,auth_hmac_sha1,auth_end};


enum cipher_mode_t {cipher_none=0,cipher_aes128cbc,cipher_xor,cipher_aes128cfb,cipher_end};
enum cipher_mode_t {cipher_none=0,cipher_aes128cbc,cipher_xor,cipher_aes128cfb,cipher_chacha12,cipher_chacha20,cipher_end};


extern auth_mode_t auth_mode;
Expand Down
127 changes: 127 additions & 0 deletions lib/chacha20.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#include <stdint.h>
#include <string.h>
#include "chacha20.h"

static inline void u32t8le(uint32_t v, uint8_t p[4]) {
p[0] = v & 0xff;
p[1] = (v >> 8) & 0xff;
p[2] = (v >> 16) & 0xff;
p[3] = (v >> 24) & 0xff;
}

static inline uint32_t u8t32le(uint8_t p[4]) {
uint32_t value = p[3];

value = (value << 8) | p[2];
value = (value << 8) | p[1];
value = (value << 8) | p[0];

return value;
}

static inline uint32_t rotl32(uint32_t x, int n) {
// http://blog.regehr.org/archives/1063
return x << n | (x >> (-n & 31));
}

// https://tools.ietf.org/html/rfc7539#section-2.1
static void chacha20_quarterround(uint32_t *x, int a, int b, int c, int d) {
x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 16);
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 12);
x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8);
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7);
}

static void chacha20_serialize(uint32_t in[16], uint8_t output[64]) {
int i;
for (i = 0; i < 16; i++) {
u32t8le(in[i], output + (i << 2));
}
}

static void chacha20_block(uint32_t in[16], uint8_t out[64], int num_rounds) {
int i;
uint32_t x[16];

memcpy(x, in, sizeof(uint32_t) * 16);

for (i = num_rounds; i > 0; i -= 2) {
chacha20_quarterround(x, 0, 4, 8, 12);
chacha20_quarterround(x, 1, 5, 9, 13);
chacha20_quarterround(x, 2, 6, 10, 14);
chacha20_quarterround(x, 3, 7, 11, 15);
chacha20_quarterround(x, 0, 5, 10, 15);
chacha20_quarterround(x, 1, 6, 11, 12);
chacha20_quarterround(x, 2, 7, 8, 13);
chacha20_quarterround(x, 3, 4, 9, 14);
}

for (i = 0; i < 16; i++) {
x[i] += in[i];
}

chacha20_serialize(x, out);
}

// https://tools.ietf.org/html/rfc7539#section-2.3
static void chacha20_init_state(uint32_t s[16], uint8_t key[32], uint32_t counter, uint8_t nonce[12]) {
int i;

// refer: https://dxr.mozilla.org/mozilla-beta/source/security/nss/lib/freebl/chacha20.c
// convert magic number to string: "expand 32-byte k"
s[0] = 0x61707865;
s[1] = 0x3320646e;
s[2] = 0x79622d32;
s[3] = 0x6b206574;

for (i = 0; i < 8; i++) {
s[4 + i] = u8t32le(key + i * 4);
}

s[12] = counter;

for (i = 0; i < 3; i++) {
s[13 + i] = u8t32le(nonce + i * 4);
}
}
void ChaCha12XOR(uint8_t key[32], uint32_t counter, uint8_t nonce[12], uint8_t *in, uint8_t *out, int inlen) {
int i, j;

uint32_t s[16];
uint8_t block[64];

chacha20_init_state(s, key, counter, nonce);

for (i = 0; i < inlen; i += 64) {
chacha20_block(s, block, 12);
s[12]++;

for (j = i; j < i + 64; j++) {
if (j >= inlen) {
break;
}
out[j] = in[j] ^ block[j - i];
}
}
}

void ChaCha20XOR(uint8_t key[32], uint32_t counter, uint8_t nonce[12], uint8_t *in, uint8_t *out, int inlen) {
int i, j;

uint32_t s[16];
uint8_t block[64];

chacha20_init_state(s, key, counter, nonce);

for (i = 0; i < inlen; i += 64) {
chacha20_block(s, block, 20);
s[12]++;

for (j = i; j < i + 64; j++) {
if (j >= inlen) {
break;
}
out[j] = in[j] ^ block[j - i];
}
}
}
9 changes: 9 additions & 0 deletions lib/chacha20.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef __CHACHA20_H
#define __CHACHA20_H
#include <stdint.h>

void ChaCha12XOR(uint8_t key[32], uint32_t counter, uint8_t nonce[12], uint8_t *input, uint8_t *output, int inputlen);

void ChaCha20XOR(uint8_t key[32], uint32_t counter, uint8_t nonce[12], uint8_t *input, uint8_t *output, int inputlen);

#endif
2 changes: 1 addition & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ cc_arm= /toolchains/arm-2014.05/bin/arm-none-linux-gnueabi-g++
#cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++
FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers ${OPT}

COMMON=main.cpp lib/md5.cpp lib/pbkdf2-sha1.cpp lib/pbkdf2-sha256.cpp encrypt.cpp log.cpp network.cpp common.cpp connection.cpp misc.cpp fd_manager.cpp client.cpp server.cpp -lpthread my_ev.cpp -isystem libev
COMMON=main.cpp lib/chacha20.c lib/md5.cpp lib/pbkdf2-sha1.cpp lib/pbkdf2-sha256.cpp encrypt.cpp log.cpp network.cpp common.cpp connection.cpp misc.cpp fd_manager.cpp client.cpp server.cpp -lpthread my_ev.cpp -isystem libev
SOURCES= $(COMMON) lib/aes_faster_c/aes.cpp lib/aes_faster_c/wrapper.cpp
SOURCES_TINY_AES= $(COMMON) lib/aes.c
SOURCES_AES_ACC=$(COMMON) $(wildcard lib/aes_acc/aes*.c)
Expand Down
2 changes: 1 addition & 1 deletion misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void print_help()
printf("common options,these options must be same on both side:\n");
printf(" --raw-mode <string> avaliable values:faketcp(default),udp,icmp\n");
printf(" -k,--key <string> password to gen symetric key,default:\"secret key\"\n");
printf(" --cipher-mode <string> avaliable values:aes128cfb,aes128cbc(default),xor,none\n");
printf(" --cipher-mode <string> avaliable values:chacha12,chacha20,aes128cfb,aes128cbc(default),xor,none\n");
printf(" --auth-mode <string> avaliable values:hmac_sha1,md5(default),crc32,simple,none\n");
printf(" -a,--auto-rule auto add (and delete) iptables rule\n");
printf(" -g,--gen-rule generate iptables rule then exit,so that you can copy and\n");
Expand Down