From 2ed654c87f48c77052ae7c02c16d13bb5294d437 Mon Sep 17 00:00:00 2001 From: Janos SUTO Date: Thu, 3 Dec 2020 18:12:48 +0100 Subject: [PATCH] Prepend a random garbage block to the data to be encrypted Signed-off-by: Janos SUTO --- src/archive.c | 15 ++++++++++++++- src/store.c | 28 +++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/archive.c b/src/archive.c index 9984c26f..f12009e2 100644 --- a/src/archive.c +++ b/src/archive.c @@ -58,6 +58,10 @@ int inf(unsigned char *in, int len, int mode, char **buffer, FILE *dest){ char *new_ptr; unsigned char out[REALLYBIGBUFSIZE]; + /* expecting deflate with 32k window size (0x78) */ + if(len > 0 && in[0] != 0x78) + return Z_DATA_ERROR; + /* allocate inflate state */ strm.zalloc = Z_NULL; @@ -139,6 +143,7 @@ int retrieve_file_from_archive(char *filename, int mode, char **buffer, FILE *de #else EVP_CIPHER_CTX *ctx=NULL; #endif + int blocklen; if(filename == NULL) return 1; @@ -162,15 +167,17 @@ int retrieve_file_from_archive(char *filename, int mode, char **buffer, FILE *de #if OPENSSL_VERSION_NUMBER < 0x10100000L EVP_CIPHER_CTX_init(&ctx); EVP_DecryptInit_ex(&ctx, EVP_bf_cbc(), NULL, cfg->key, cfg->iv); + blocklen = EVP_CIPHER_CTX_block_size(&ctx); #else ctx = EVP_CIPHER_CTX_new(); if(!ctx) goto CLEANUP; EVP_CIPHER_CTX_init(ctx); EVP_DecryptInit_ex(ctx, EVP_bf_cbc(), NULL, cfg->key, cfg->iv); + blocklen = EVP_CIPHER_CTX_block_size(ctx); #endif - len = st.st_size+EVP_MAX_BLOCK_LENGTH; + len = st.st_size+blocklen; s = malloc(len); @@ -207,7 +214,13 @@ int retrieve_file_from_archive(char *filename, int mode, char **buffer, FILE *de tlen += olen; + + // old fileformat with static IV rc = inf(s, tlen, mode, buffer, dest); + // new fileformat, starting with blocklen bytes of garbage + if(rc != Z_OK && tlen >= blocklen){ + rc = inf(s+blocklen, tlen-blocklen, mode, buffer, dest); + } } else { addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); diff --git a/src/store.c b/src/store.c index d903282d..29e11907 100644 --- a/src/store.c +++ b/src/store.c @@ -51,6 +51,8 @@ int store_file(struct session_data *sdata, char *filename, int len, struct confi #else EVP_CIPHER_CTX *ctx; #endif + int blocklen; + unsigned char rnd[EVP_MAX_BLOCK_LENGTH]; unsigned char *outbuf=NULL; int outlen=0, writelen, tmplen; @@ -108,25 +110,45 @@ int store_file(struct session_data *sdata, char *filename, int len, struct confi #if OPENSSL_VERSION_NUMBER < 0x10100000L EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, cfg->key, cfg->iv); + blocklen = EVP_CIPHER_CTX_block_size(&ctx); #else ctx = EVP_CIPHER_CTX_new(); if(!ctx) goto ENDE; EVP_CIPHER_CTX_init(ctx); EVP_EncryptInit_ex(ctx, EVP_bf_cbc(), NULL, cfg->key, cfg->iv); + blocklen = EVP_CIPHER_CTX_block_size(ctx); #endif - outbuf = malloc(dstlen + EVP_MAX_BLOCK_LENGTH); + // prepend a block with random data as replacement for dynamic iv + // see e.g. https://crypto.stackexchange.com/questions/5421/using-cbc-with-a-fixed-iv-and-a-random-first-plaintext-block + fd = open(RANDOM_POOL, O_RDONLY); + if(fd == -1) goto ENDE; + tmplen = readFromEntropyPool(fd, rnd, blocklen); + close(fd); + if(tmplen != blocklen) goto ENDE; + // make sure, random data does not start with zlib magic 0x78 + if(rnd[0] == 0x78) rnd[0] =~ rnd[0]; + + outbuf = malloc(dstlen + blocklen * 2); if(outbuf == NULL) goto ENDE; #if OPENSSL_VERSION_NUMBER < 0x10100000L - if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, z, dstlen)) goto ENDE; + if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, rnd, blocklen)) goto ENDE; + if(!EVP_EncryptUpdate(&ctx, outbuf + outlen, &tmplen, z, dstlen)) goto ENDE; + #else + if(!EVP_EncryptUpdate(ctx, outbuf, &outlen, rnd, blocklen)) goto ENDE; + if(!EVP_EncryptUpdate(ctx, outbuf + outlen, &tmplen, z, dstlen)) goto ENDE; + #endif + outlen += tmplen; + + #if OPENSSL_VERSION_NUMBER < 0x10100000L if(!EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen)) goto ENDE; #else - if(!EVP_EncryptUpdate(ctx, outbuf, &outlen, z, dstlen)) goto ENDE; if(!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen)) goto ENDE; #endif outlen += tmplen; + #if OPENSSL_VERSION_NUMBER < 0x10100000L EVP_CIPHER_CTX_cleanup(&ctx); #else