commit 682e2bff0cd7118c454c552377b9ed45fe8a02a8
parent 7f142b1eb0f5738d4ad7cdfa70a012a5a9e18fc9
Author: Dominik Schmidt <dominik@schm1dt.ch>
Date: Tue, 25 Dec 2018 13:05:22 +0100
Introduce the iv_inband KV switch, that uses the first BLOCK_SIZE bytes of the input as IV
Diffstat:
nettle.c | | | 56 | +++++++++++++++++++++++++++++++++++++++++++++----------- |
1 file changed, 45 insertions(+), 11 deletions(-)
diff --git a/nettle.c b/nettle.c
@@ -39,7 +39,7 @@ struct EncStage{
uint8_t* dst;
String key;
String iv;
-
+ int iv_inband;
};
String readFile(FILE *f, size_t maxSize){
@@ -245,6 +245,13 @@ int parseKV(struct EncStage *es, char *args){
else if(strcmp("iv", k)==0){
es->iv=argString(v);
}
+ else if(strcmp("iv_inband", k)==0){
+ es->iv_inband=atoi(v);
+ if(es->iv_inband!=0 && es->iv_inband!=1){
+ fprintf(stderr, "iv_inband has to be either 1 or 0, not %s\n", v);
+ return 1;
+ }
+ }
else{
fprintf(stderr, "Key %s not known\n", k);
return 1;
@@ -326,7 +333,12 @@ const char *encDirToString(enum DIRECTION ed){
}
void fprintEncStage(FILE *f, struct EncStage *es){
- 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);
+ if(es->iv_inband==0){
+ 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);
+ }
+ else{
+ 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);
+ }
}
void usage(){
@@ -379,15 +391,28 @@ void CFBDecrypt(void *state, struct EncStage *es){
int execute(struct EncStage *es){
- size_t ctx_s=es->cipher->context_size;
- void *ctx=malloc(ctx_s);
- memset(ctx, 0, ctx_s);
-
- if(es->iv.len == 0){
+ int free_iv=0;
+ if(es->iv_inband == 1){
+ es->iv.len=es->cipher->block_size;
+ es->iv.str=es->src;
+ es->src+=es->iv.len;
+ es->len-=es->iv.len;
+ es->dst+=es->iv.len;
+ }
+ else if(es->iv.len == 0){
es->iv.len=es->cipher->block_size;
es->iv.str=malloc(es->iv.len);
memset(es->iv.str, 0, es->iv.len);
+ free_iv=1;
+ }
+ else if(es->iv.len != es->cipher->block_size){
+ fprintf(stderr, "IV has to be exactly one block size, is %lu\n", es->iv.len);
+ return 1;
}
+ size_t ctx_s=es->cipher->context_size;
+ void *ctx=malloc(ctx_s);
+ memset(ctx, 0, ctx_s);
+
switch(es->dir){
case ENCRYPT:
@@ -412,6 +437,10 @@ int execute(struct EncStage *es){
if(es->dir==ENCRYPT) CFBEncrypt(ctx, es); else CFBDecrypt(ctx, es);
break;
}
+ if(free_iv){
+ free(es->iv.str);
+ es->iv.len=0;
+ }
free(ctx);
return 0;
}
@@ -427,8 +456,10 @@ int main(int argc, char **argv){
String s=readFile(stdin, SIZE_MAX);
String s2;
char *in=s.str;
- char *out=NULL;
+ char *out=s.str;
+ size_t len=s.len;
for(i=1; i<argc; i++){
+
memset(&es, 0, sizeof(typeof(es)));
ret=fillEncStage(&es, argv[i]);
if(ret!=0){
@@ -438,17 +469,20 @@ int main(int argc, char **argv){
fprintEncStage(stderr, &es);
//char *out=malloc(s.len);
//memset(out, 0x00, s.len);
- es.len=s.len;
+ es.len=len;
es.src=in;
- es.dst=in;
+ es.dst=out;
if(execute(&es)!=0){
return 1;
}
+ len=es.len;
+ in=es.src;
+ out=es.dst;
//char *tmp=in;
//in=out;
//free(tmp);
}
- fwrite(in, 1, s.len, stdout);
+ fwrite(es.dst, 1, es.len, stdout);
return 0;
}