added aes initialization vector

Mon, 12 Aug 2013 19:50:14 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 12 Aug 2013 19:50:14 +0200
changeset 10
e6d0fbe0ebd9
parent 9
6aec77cfa95b
child 11
5db6178d8b58

added aes initialization vector

dav/crypto.c file | annotate | diff | comparison | revisions
dav/crypto.h file | annotate | diff | comparison | revisions
--- 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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/rand.h>
 
 #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);
 }
 
--- 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;

mercurial