# HG changeset patch # User Olaf Wintermann # Date 1376329814 -7200 # Node ID e6d0fbe0ebd947e855ee5d11029efc9712532890 # Parent 6aec77cfa95b7f99adecf3909512e60323d387c5 added aes initialization vector diff -r 6aec77cfa95b -r e6d0fbe0ebd9 dav/crypto.c --- a/dav/crypto.c Mon Aug 12 16:32:30 2013 +0200 +++ b/dav/crypto.c Mon Aug 12 19:50:14 2013 +0200 @@ -29,6 +29,7 @@ #include #include #include +#include #include "crypto.h" @@ -36,21 +37,54 @@ AESDecrypter *dec = malloc(sizeof(AESDecrypter)); dec->stream = stream; dec->write = write_func; + dec->key = key; + dec->init = 0; + dec->ivpos = 0; + return dec; +} + +void aes_decrypter_init(AESDecrypter *dec) { EVP_CIPHER_CTX_init(&dec->ctx); - if(key->type == KEY_AES128) { - EVP_DecryptInit_ex(&dec->ctx, EVP_aes_128_cbc(), NULL, key->data, NULL); - } else if(key->type == KEY_AES256) { - EVP_DecryptInit_ex(&dec->ctx, EVP_aes_256_cbc(), NULL, key->data, NULL); + dec->init = 1; + if(dec->key->type == KEY_AES128) { + EVP_DecryptInit_ex( + &dec->ctx, + EVP_aes_128_cbc(), + NULL, + dec->key->data, + dec->ivtmp); + } else if(dec->key->type == KEY_AES256) { + EVP_DecryptInit_ex( + &dec->ctx, + EVP_aes_256_cbc(), + NULL, + dec->key->data, + dec->ivtmp); } else { fprintf(stderr, "unknown key type\n"); exit(-1); } - return dec; } size_t aes_write(const void *buf, size_t s, size_t n, AESDecrypter *dec) { int len = s*n; + if(!dec->init) { + size_t n = 16 - dec->ivpos; + size_t cp = n > len ? len : n; + memcpy(dec->ivtmp + dec->ivpos, buf, cp); + dec->ivpos += cp; + if(dec->ivpos >= 16) { + aes_decrypter_init(dec); + } + if(len == cp) { + return len; + } else { + buf = (char*)buf + cp; + len -= cp; + } + } + int outlen = len + 16; unsigned char *out = malloc(outlen); EVP_DecryptUpdate(&dec->ctx, out, &len, buf, len); @@ -71,6 +105,12 @@ AESEncrypter* aes_encrypter_new(Key *key, void *stream, dav_read_func read_func) { + unsigned char *iv = malloc(16); + if(!RAND_bytes(iv, 16)) { + free(iv); + return NULL; + } + AESEncrypter *enc = malloc(sizeof(AESEncrypter)); enc->stream = stream; enc->read = read_func; @@ -78,12 +118,15 @@ enc->tmplen = 0; enc->tmpoff = 0; enc->end = 0; + //enc->iv = iv; + enc->iv = iv; + enc->ivlen = 16; EVP_CIPHER_CTX_init(&enc->ctx); if(key->type == KEY_AES128) { - EVP_EncryptInit_ex(&enc->ctx, EVP_aes_128_cbc(), NULL, key->data, NULL); + EVP_EncryptInit_ex(&enc->ctx, EVP_aes_128_cbc(), NULL, key->data, enc->iv); } else if(key->type == KEY_AES256) { - EVP_EncryptInit_ex(&enc->ctx, EVP_aes_256_cbc(), NULL, key->data, NULL); + EVP_EncryptInit_ex(&enc->ctx, EVP_aes_256_cbc(), NULL, key->data, enc->iv); } else { fprintf(stderr, "unknown key type\n"); exit(-1); @@ -114,22 +157,30 @@ void *in = malloc(len); size_t in_len = enc->read(in, 1, len, enc->stream); - void *out = NULL; + unsigned char *out = NULL; int outlen = 0; + size_t ivl = enc->ivlen; if(in_len != 0) { outlen = len + 16; - out = malloc(outlen); - EVP_EncryptUpdate(&enc->ctx, out, &outlen, in, in_len); - //out = (char*)aes_encrypt(enc->ctx, (unsigned char*)in, (int*)&in_len); + out = malloc(outlen + ivl); + if(enc->iv) { + memcpy(out, enc->iv, ivl); + } + EVP_EncryptUpdate(&enc->ctx, out + ivl, &outlen, in, in_len); } else { out = malloc(16); EVP_EncryptFinal_ex(&enc->ctx, out, &outlen); enc->end = 1; } - enc->tmp = out; - enc->tmplen = outlen; + enc->tmp = (char*)out; + enc->tmplen = outlen + ivl; enc->tmpoff = 0; + if(enc->iv) { + enc->iv = NULL; + enc->ivlen = 0; + } + return aes_read(buf, s, n, enc); } diff -r 6aec77cfa95b -r e6d0fbe0ebd9 dav/crypto.h --- a/dav/crypto.h Mon Aug 12 16:32:30 2013 +0200 +++ b/dav/crypto.h Mon Aug 12 19:50:14 2013 +0200 @@ -41,10 +41,16 @@ EVP_CIPHER_CTX ctx; void *stream; dav_write_func write; + Key *key; + int init; + unsigned char ivtmp[16]; + size_t ivpos; } AESDecrypter; typedef struct { EVP_CIPHER_CTX ctx; + void *iv; + size_t ivlen; void *stream; dav_read_func read; char *tmp;