fix aes decrypter stream

Wed, 04 Dec 2019 15:18:15 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 04 Dec 2019 15:18:15 +0100
changeset 689
b1f7d83f6e69
parent 688
d405d2ac78e6
child 690
ce253cfb9127

fix aes decrypter stream

libidav/crypto.c file | annotate | diff | comparison | revisions
libidav/crypto.h file | annotate | diff | comparison | revisions
--- a/libidav/crypto.c	Wed Dec 04 11:47:51 2019 +0100
+++ b/libidav/crypto.c	Wed Dec 04 15:18:15 2019 +0100
@@ -1018,7 +1018,7 @@
     dec->key = key;
     dec->init = 0;
     dec->ivpos = 0;
-    
+      
     return dec;
 }
 
@@ -1034,6 +1034,8 @@
 size_t aes_write(const void *buf, size_t s, size_t n, AESDecrypter *dec) {
     int len = s*n;
     if(!dec->init) {
+        dec->init = 1;
+        
         size_t n = 16 - dec->ivpos;
         size_t cp = n > len ? len : n;
         memcpy(dec->ivtmp + dec->ivpos, buf, cp);
@@ -1052,7 +1054,7 @@
     // the cipher text must be a multiply of 16
     // remaining bytes are stored in ctx.buf and must be added to cibuf
     // the next time
-    size_t cbufalloc = len + 32;
+    size_t cbufalloc = len + 64;
     ULONG clen = 0;
     char *cbuf = malloc(cbufalloc);
     
@@ -1067,30 +1069,39 @@
     
     // check if the message fits the blocksize
     int remaining = clen % 16;
-    if(remaining > 0) {
-        // add remaining bytes to ctx.buf for the next aes_write run
-        clen -= remaining;
-        memcpy(dec->ctx.buf, cbuf + clen - remaining, remaining);
+    if(remaining == 0) {
+        // decrypt last block next time, or in aes_decrypter_shutdown
+        // this makes sure, that shutdown always decrypts the last block
+        // with BCRYPT_BLOCK_PADDING flag
+        remaining = 16;
     }
+    
+    // add remaining bytes to ctx.buf for the next aes_write run
+    clen -= remaining;
+    memcpy(dec->ctx.buf, cbuf + clen, remaining);
     dec->ctx.buflen = remaining;
     
     // ready to decrypt the message
     ULONG outlen = clen + 32;
     unsigned char *out = malloc(outlen);
-    
+       
     // decrypt
     if(clen > 0) {
-        if(BCryptDecrypt(dec->ctx.hKey, cbuf, clen, NULL, dec->ctx.pbIV, 16, out, outlen, &outlen, BCRYPT_BLOCK_PADDING)) {
-            fprintf(stderr, "Error: BCryptDecrypt failed\n");
+        ULONG enc_len = 0;
+        ULONG status = BCryptDecrypt(dec->ctx.hKey, cbuf, clen, NULL, dec->ctx.pbIV, 16, out, outlen, &enc_len, 0);
+        if(status > 0) {
+            fprintf(stderr, "Error: BCryptDecrypt failed: 0x%X\n", status);
             free(out);
             free(cbuf);
             return 0;
-        }
+        }      
+        outlen = enc_len;
     }
     
     // write decrypted data to the output stream and update the hash
     dec->write(out, 1, outlen, dec->stream);
     BCryptHashData(dec->sha256.hHash, out, outlen, 0);
+    
     free(out);
     free(cbuf);
     
@@ -1098,7 +1109,7 @@
 }
 
 void aes_decrypter_shutdown(AESDecrypter *dec) {
-    if(dec->init && dec->ctx.buflen > 0) {
+    if(dec->init && dec->ctx.buflen > 0) { 
         ULONG outlen = 64;
         char out[64];
         if(BCryptDecrypt(dec->ctx.hKey, dec->ctx.buf, dec->ctx.buflen, NULL, dec->ctx.pbIV, 16, out, outlen, &outlen, BCRYPT_BLOCK_PADDING)) {
--- a/libidav/crypto.h	Wed Dec 04 11:47:51 2019 +0100
+++ b/libidav/crypto.h	Wed Dec 04 15:18:15 2019 +0100
@@ -57,8 +57,8 @@
     void              *pbKeyObject;
     unsigned char     pbIV[16];
     
-    char              buf[16];
-    size_t            buflen;
+    unsigned char     buf[16];
+    ULONG             buflen;
 } WinBCryptCTX;
 
 typedef struct WinBCryptSHACTX {

mercurial