nettleif

git clone git://xatko.vsos.ethz.ch/nettleif.git
Log | Files | Refs

nettle.c (13018B)


      1 #include <nettle/nettle-meta.h>
      2 #include <nettle/cbc.h>
      3 #include <nettle/aes.h>
      4 #include <nettle/ctr.h>
      5 #include <nettle/cfb.h>
      6 #include <nettle/blowfish.h>
      7 #include <nettle/arcfour.h>
      8 #include <nettle/macros.h>
      9 #include <string.h>
     10 #include <stdlib.h>
     11 #include <stdio.h>
     12 #include <stdint.h>
     13 
     14 #if defined(_WIN32)
     15 	#include <io.h>
     16 	#include <fcntl.h>
     17 #endif
     18 
     19 enum MODE{
     20 	ECB,
     21 	CBC,
     22 	CTR,
     23 	CFB,
     24 	INVALID
     25 };
     26 
     27 enum DIRECTION{
     28 	ENCRYPT,
     29 	DECRYPT
     30 };
     31 
     32 typedef struct{
     33 	size_t len;
     34 	char *str;
     35 }  String;
     36 
     37 struct EncStage{
     38 	enum MODE mode;
     39 	enum DIRECTION dir;
     40 	const struct nettle_cipher *cipher;
     41 	
     42 	size_t len;
     43 	uint8_t* src;
     44 	uint8_t* dst;
     45 	String key;
     46 	String iv;
     47 	int iv_inband;
     48 };
     49 
     50 String readFile(FILE *f, size_t maxSize){
     51 	size_t ret=0;
     52 	size_t alloc=1024;
     53 	size_t size=0;
     54 	uint8_t *buf=NULL;
     55 	while(1){
     56 		buf=realloc(buf, alloc);
     57 		if(buf==NULL){
     58 			fprintf(stderr, "Allocation failure\n");
     59 		}
     60 		ret=fread(buf+size, 1, alloc-size, f);
     61 		size+=ret;
     62 		if(ret<alloc-size){
     63 			break;
     64 		}
     65 	}
     66 	buf[size]='\0';
     67 	String s={.len=size, .str=buf};
     68 	return s;
     69 }
     70 
     71 String argString(char *arg){
     72 	if(arg[0]=='@'){
     73 		if(arg[1]=='@'){
     74 			return (String){.str=&arg[2],.len=strlen(&arg[2])};
     75 		}
     76 		else{
     77 			FILE *f=fopen(&arg[1], "r");
     78 			if(f==NULL){
     79 				perror("Could not open file");
     80 				return (String){.str=NULL,.len=0};
     81 			}
     82 			String ret=readFile(f, SIZE_MAX);
     83 			if(ret.str==NULL){
     84 				fprintf(stderr, "Couldnt read file\n");
     85 			}
     86 			return ret;
     87 			
     88 		}
     89 	}
     90 	else{
     91 		return (String){.str=arg, .len=strlen(arg)};
     92 	}
     93 }
     94 
     95 const static size_t tea_block_size=4*2;
     96 const static size_t tea_key_size=4*4;
     97 const static size_t tea_context_size=tea_key_size;
     98 
     99 void tea_encrypt_block (uint32_t v[2], const uint32_t k[4]) {
    100     uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */
    101     uint32_t delta=0x9E3779B9;                     /* a key schedule constant */
    102     uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    103     for (i=0; i<32; i++) {                         /* basic cycle start */
    104         sum += delta;
    105         v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
    106         v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
    107     }                                              /* end cycle */
    108     v[0]=v0; v[1]=v1;
    109 }
    110 
    111 void tea_decrypt_block (uint32_t v[2], const uint32_t k[4]) {
    112     uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up; sum is 32*delta */
    113     uint32_t delta=0x9E3779B9;                     /* a key schedule constant */
    114     uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    115     for (i=0; i<32; i++) {                         /* basic cycle start */
    116         v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
    117         v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
    118         sum -= delta;
    119     }                                              /* end cycle */
    120     v[0]=v0; v[1]=v1;
    121 }
    122 
    123 void tea_encrypt(const void *ctx, size_t len, uint8_t *dst, const uint8_t *src){
    124 	memcpy(dst, src, len);
    125 	uint8_t *cur;
    126 	//assert(!(len%tea_block_size));
    127 	for(cur=dst; cur<dst+len; cur+=tea_block_size){
    128 		tea_encrypt_block((uint32_t*)cur, (uint32_t*)ctx);
    129 	}
    130 }
    131 
    132 void tea_decrypt(const void *ctx, size_t len, uint8_t *dst, const uint8_t *src){
    133 	memcpy(dst, src, len);
    134 	uint8_t *cur;
    135 	//assert(!(len%tea_block_size));
    136 	for(cur=dst; cur<dst+len; cur+=tea_block_size){
    137 		tea_decrypt_block((uint32_t*)cur, (uint32_t*)ctx);
    138 	}
    139 }
    140 
    141 void tea_set_key(void *ctx, const uint8_t *key){
    142 	memcpy(ctx, key, tea_key_size);
    143 }
    144 
    145 const struct nettle_cipher nettle_tea={
    146 	.name="tea128",
    147 	.context_size=tea_context_size,
    148 	.block_size=tea_block_size,
    149 	.key_size=tea_key_size,
    150 	.set_encrypt_key=&tea_set_key,
    151 	.set_decrypt_key=&tea_set_key,
    152 	.encrypt=&tea_encrypt,
    153 	.decrypt=&tea_decrypt
    154 };
    155 
    156 const struct nettle_cipher nettle_blowfish128={
    157 	.name="blowfish128",
    158 	.context_size=sizeof(struct blowfish_ctx),
    159 	.block_size=BLOWFISH_BLOCK_SIZE,
    160 	.key_size=BLOWFISH_KEY_SIZE,
    161 	.set_encrypt_key=&blowfish128_set_key,
    162 	.set_decrypt_key=&blowfish128_set_key,
    163 	.encrypt=&blowfish_encrypt,
    164 	.decrypt=&blowfish_decrypt
    165 };
    166 
    167 const struct nettle_cipher nettle_arcfour128={
    168 	.name="arcfour128",
    169 	.context_size=sizeof(struct arcfour_ctx),
    170 	.block_size=1,
    171 	.key_size=16,
    172 	.set_encrypt_key=&arcfour128_set_key,
    173 	.set_decrypt_key=&arcfour128_set_key,
    174 	.encrypt=&arcfour_crypt,
    175 	.decrypt=&arcfour_crypt
    176 };
    177 
    178 const struct nettle_cipher nettle_blowfish={
    179 	.name="blowfish",
    180 	.context_size=sizeof(struct blowfish_ctx),
    181 	.block_size=BLOWFISH_BLOCK_SIZE,
    182 	.key_size=BLOWFISH_KEY_SIZE,
    183 	.set_encrypt_key=&blowfish128_set_key,
    184 	.set_decrypt_key=&blowfish128_set_key,
    185 	.encrypt=&blowfish_encrypt,
    186 	.decrypt=&blowfish_decrypt
    187 };
    188 
    189 const struct nettle_cipher nettle_arcfour={
    190 	.name="arcfour",
    191 	.context_size=sizeof(struct arcfour_ctx),
    192 	.block_size=1,
    193 	.key_size=16,
    194 	.set_encrypt_key=&arcfour128_set_key,
    195 	.set_decrypt_key=&arcfour128_set_key,
    196 	.encrypt=&arcfour_crypt,
    197 	.decrypt=&arcfour_crypt
    198 };
    199 
    200 const struct nettle_cipher *own_list[]={&nettle_tea, &nettle_blowfish128, &nettle_arcfour128, &nettle_blowfish, &nettle_arcfour, NULL};
    201 
    202 /*
    203 void ecb(void *ctx, nettle_cipher_func f, size_t blocklen, size_t len, uint8_t *dst, uint8_t *src){
    204 	uint8_t *cur;
    205 	uint8_t *curd=dst;
    206 	for(cur=src; cur<src+len; cur+=blocklen){
    207 		f(ctx, blocklen, curd, cur);
    208 		curd+=blocklen;
    209 	}
    210 }
    211 
    212 void tea_encrypt(void *ctx
    213 */
    214 
    215 const struct nettle_cipher* getCipherFromList(char *args, const struct nettle_cipher* const* nc){
    216 	for(; *nc!=NULL; nc++){
    217 		if(strcmp((*nc)->name, args)==0){
    218 			break;
    219 		}
    220 	}
    221 	return *nc;
    222 }
    223 
    224 const struct nettle_cipher* getCipher(char *args){
    225 	const struct nettle_cipher * nc;
    226 	nc=getCipherFromList(args, nettle_get_ciphers());
    227 	if(nc!=NULL){
    228 		return nc;
    229 	}
    230 	nc=getCipherFromList(args, own_list);
    231 	return nc;
    232 }
    233 
    234 enum MODE getMode(char *args){
    235 	if(strcmp(args, "CBC")==0){
    236 		return CBC;
    237 	}
    238 	else if(strcmp(args, "CTR")==0){
    239 		return CTR;
    240 	}
    241 	else if(strcmp(args, "CFB")==0){
    242 		return CFB;
    243 	}
    244 	else if(strcmp(args, "ECB")==0){
    245 		return ECB;
    246 	}
    247 	else{
    248 		return INVALID;
    249 	}
    250 }
    251 
    252 int parseKV(struct EncStage *es, char *args){
    253 	while(args!=NULL && *args!='\0'){
    254 		char *k=args;
    255 		char *kv=strstr(args, ",");
    256 		if(kv!=NULL){
    257 			*kv++='\0';
    258 			args=kv;
    259 		}
    260 		else{
    261 			args=NULL;
    262 		}
    263 		char *v=strstr(k, "=");
    264 		if(v==NULL){
    265 			es->key=(String){.str=k,.len=strlen(k)};
    266 		}
    267 		else{
    268 			*v++='\0';
    269 			if(strcmp("key", k)==0){
    270 				es->key=argString(v);
    271 			}
    272 			else if(strcmp("iv", k)==0){
    273 				es->iv=argString(v);
    274 			}
    275 			else if(strcmp("iv_inband", k)==0){
    276 				es->iv_inband=atoi(v);
    277 				if(es->iv_inband!=0 && es->iv_inband!=1){
    278 					fprintf(stderr, "iv_inband has to be either 1 or 0, not %s\n", v);
    279 					return 1;
    280 				}
    281 			}
    282 			else{
    283 				fprintf(stderr, "Key %s not known\n", k);
    284 				return 1;
    285 			}
    286 		}
    287 	}
    288 	return 0;
    289 }
    290 
    291 int fillEncStage(struct EncStage *es, char *args){
    292 	switch(args[0]){
    293 		case '+':
    294 			es->dir=ENCRYPT;
    295 			break;
    296 		case '-':
    297 			es->dir=DECRYPT;
    298 			break;
    299 		default:
    300 			fprintf(stderr, "Malformed argument. + or - expected, got %c\n", args[0]);
    301 			return 1;
    302 			break;
    303 	}
    304 	args++;
    305 	
    306 	char *cipher=strstr(args, ":");
    307 	if(cipher == NULL){
    308 		fprintf(stderr, "Colon (:) expected to denote the cipher mode\n");
    309 		return 1;
    310 	}
    311 	*cipher++='\0';
    312 	es->mode=getMode(args);
    313 	if(es->mode == INVALID){
    314 		fprintf(stderr, "Cipher mode %s unknown.\n", args);
    315 		return 1;
    316 	}
    317 	
    318 	char *kv=strstr(cipher, ":");
    319 	if(kv!=NULL){
    320 		*kv++='\0';
    321 		if(parseKV(es, kv)!=0){
    322 			return 1;
    323 		}
    324 	}
    325 	
    326 	es->cipher=getCipher(cipher);
    327 	if(es->cipher == NULL){
    328 		fprintf(stderr, "cipher %s not known\n", cipher);
    329 		return 1;
    330 	}
    331 	return 0;
    332 }
    333 
    334 const char *modeToString(enum MODE m){
    335 	switch(m){
    336 		case CBC:
    337 			return "CBC";
    338 		case CTR:
    339 			return "CTR";
    340 		case CFB:
    341 			return "CFB";
    342 		case ECB:
    343 			return "ECB";
    344 		case INVALID:
    345 		default:
    346 			return "Invalid";
    347 		
    348 	}
    349 }
    350 
    351 const char *encDirToString(enum DIRECTION ed){
    352 	switch(ed){
    353 		case ENCRYPT:
    354 			return "Encryption";
    355 		case DECRYPT:
    356 			return "Decryption";
    357 		default:
    358 			return "Invalid";
    359 	}
    360 }
    361 
    362 void fprintEncStage(FILE *f, struct EncStage *es){
    363 	if(es->iv_inband==0){
    364 		fprintf(f, "%s using cipher %s in %s-Mode with key \"%s\" and IV \"%s\"\n", encDirToString(es->dir), es->cipher->name, modeToString(es->mode), es->key.str, es->iv.str);
    365 	}
    366 	else{
    367 		fprintf(f, "%s using cipher %s in %s-Mode with key \"%s\" and IV the first %u bytes from input\n", encDirToString(es->dir), es->cipher->name, modeToString(es->mode), es->key.str, es->cipher->block_size);
    368 	}
    369 }
    370 
    371 void usage(){
    372 	const struct nettle_cipher * const *nc;
    373 	printf("Usage: nettle [-h | --help] <cipher_spec> [cipher_spec...]\n"\
    374 		"cipher_spec: direction ':' cipher [ ':' key_values ]\n"\
    375 		"direction: '+' | '-'\n"\
    376 		"cipher: string\n"\
    377 		"key_values: key_value | key_value ',' key_values\n"\
    378 		"key_value: key '=' value\n"\
    379 		"key: 'key' | 'iv' | 'iv_inband'\n"\
    380 		"value: '@' file | string\n\n"
    381 	);
    382 	printf("Example: nettle -CBC:aes128:key=\"BENALOH PAILLIER\",iv=@iv.dat < HALOS.bin\n"\
    383 		"This prints to STDOUT a decryption in CBC mode using AES with 128 bits key length,\n"\
    384 		"using \"BENALOH PAILLIER\" as key and reading the initialization vector from the file iv.dat\n\n");
    385 	printf("Available ciphers names: \n");
    386 	for(nc=nettle_get_ciphers(); *nc!=NULL; nc++){
    387 		printf("%s\n", (*nc)->name);
    388 	}
    389 	for(nc=own_list; *nc!=NULL; nc++){
    390 		printf("%s\n", (*nc)->name);
    391 	}
    392 }
    393 
    394 void ECBEncrypt(void *state, struct EncStage *es){
    395 	es->cipher->encrypt(state, es->len, es->dst, es->src);
    396 }
    397 void ECBDecrypt(void *state, struct EncStage *es){
    398 	es->cipher->decrypt(state, es->len, es->dst, es->src);
    399 }
    400 void CBCEncrypt(void *state, struct EncStage *es){
    401 	cbc_encrypt(state, es->cipher->encrypt, es->cipher->block_size, es->iv.str, es->len, es->dst, es->src);
    402 }
    403 void CBCDecrypt(void *state, struct EncStage *es){
    404 	cbc_decrypt(state, es->cipher->decrypt, es->cipher->block_size, es->iv.str, es->len, es->dst, es->src);
    405 }
    406 void CTREncrypt(void *state, struct EncStage *es){
    407 	ctr_crypt(state, es->cipher->encrypt, es->cipher->block_size, es->iv.str, es->len, es->dst, es->src);
    408 }
    409 void CTRDecrypt(void *state, struct EncStage *es){
    410 	ctr_crypt(state, es->cipher->decrypt, es->cipher->block_size, es->iv.str, es->len, es->dst, es->src);
    411 }
    412 void CFBEncrypt(void *state, struct EncStage *es){
    413 	cfb_encrypt(state, es->cipher->encrypt, es->cipher->block_size, es->iv.str, es->len, es->dst, es->src);
    414 }
    415 void CFBDecrypt(void *state, struct EncStage *es){
    416 	cfb_decrypt(state, es->cipher->decrypt, es->cipher->block_size, es->iv.str, es->len, es->dst, es->src);
    417 }
    418 
    419 
    420 int execute(struct EncStage *es){
    421 	int free_iv=0;
    422 	if(es->iv_inband == 1){
    423 		es->iv.len=es->cipher->block_size;
    424 		es->iv.str=es->src;
    425 		es->src+=es->iv.len;
    426 		es->len-=es->iv.len;
    427 		es->dst+=es->iv.len;
    428 	}
    429 	else if(es->iv.len == 0){
    430 		es->iv.len=es->cipher->block_size;
    431 		es->iv.str=malloc(es->iv.len);
    432 		memset(es->iv.str, 0, es->iv.len);
    433 		free_iv=1;
    434 	}
    435 	else if(es->iv.len != es->cipher->block_size){
    436 		fprintf(stderr, "IV has to be exactly one block size, is %lu\n", es->iv.len);
    437 		return 1;
    438 	}
    439 	size_t ctx_s=es->cipher->context_size;
    440 	void *ctx=malloc(ctx_s);
    441 	memset(ctx, 0, ctx_s);
    442 	
    443 	if(es->cipher->name=="arcfour"){
    444 		if(es->key.len < ARCFOUR_MIN_KEY_SIZE || es->key.len > ARCFOUR_MAX_KEY_SIZE){
    445 			fprintf(stderr, "Key length %ld not suited for arcfour", es->key.len);
    446 			return 1;
    447 		}
    448 		arcfour_set_key((struct arcfour_ctx *)ctx, es->key.len, es->key.str);
    449 	}
    450 	else if(es->cipher->name == "blowfish"){
    451 		if(es->key.len < BLOWFISH_MIN_KEY_SIZE || es->key.len > BLOWFISH_MAX_KEY_SIZE){
    452 			fprintf(stderr, "Key length %ld not suited for blowfish", es->key.len);
    453 			return 1;
    454 		}
    455 		blowfish_set_key((struct blowfish_ctx *)ctx, es->key.len, es->key.str);
    456 	}
    457 	else{
    458 		switch(es->dir){
    459 			case ENCRYPT:
    460 				es->cipher->set_encrypt_key(ctx, es->key.str);
    461 				break;
    462 			case DECRYPT:
    463 				es->cipher->set_decrypt_key(ctx, es->key.str);
    464 				break;
    465 		}
    466 	}
    467 	
    468 	switch(es->mode){
    469 		case ECB:
    470 			if(es->dir==ENCRYPT) ECBEncrypt(ctx, es); else ECBDecrypt(ctx, es);
    471 			break;
    472 		case CBC:
    473 			if(es->dir==ENCRYPT) CBCEncrypt(ctx, es); else CBCDecrypt(ctx, es);
    474 			break;
    475 		case CTR:
    476 			if(es->dir==ENCRYPT) CTREncrypt(ctx, es); else CTRDecrypt(ctx, es);
    477 			break;
    478 		case CFB:
    479 			if(es->dir==ENCRYPT) CFBEncrypt(ctx, es); else CFBDecrypt(ctx, es);
    480 			break;
    481 	}
    482 	if(free_iv){
    483 		free(es->iv.str);
    484 		es->iv.len=0;
    485 	}
    486 	free(ctx);
    487 	return 0;
    488 }
    489 
    490 int main(int argc, char **argv){
    491 	if(argc>1 && (strcmp(argv[1], "-h")==0 || strcmp(argv[1], "--help")==0)){
    492 		usage();
    493 		return 0;
    494 	}
    495 	struct EncStage es;
    496 	int ret;
    497 	int i;
    498 	#if defined(_WIN32)
    499 		_setmode(_fileno(stdin), _O_BINARY);
    500 	#endif
    501 	String s=readFile(stdin, SIZE_MAX);
    502 	String s2;
    503 	char *in=s.str;
    504 	char *out=s.str;
    505 	size_t len=s.len;
    506 	for(i=1; i<argc; i++){
    507 		
    508 		memset(&es, 0, sizeof(typeof(es)));
    509 		ret=fillEncStage(&es, argv[i]);
    510 		if(ret!=0){
    511 			usage();
    512 			return 1;
    513 		}
    514 		fprintEncStage(stderr, &es);
    515 		//char *out=malloc(s.len);
    516 		//memset(out, 0x00, s.len);
    517 		es.len=len;
    518 		es.src=in;
    519 		es.dst=out;
    520 		
    521 		if(execute(&es)!=0){
    522 			return 1;
    523 		}
    524 		len=es.len;
    525 		in=es.src;
    526 		out=es.dst;
    527 		//char *tmp=in;
    528 		//in=out;
    529 		//free(tmp);
    530 	}
    531 	fwrite(es.dst, 1, es.len, stdout);
    532 	return 0;
    533 }