1

(5 replies, posted in wolfCrypt)

Thanks for getting back to me, Kaleb.

I'm working on Linux on x86_64 here; a laptopt with a Core i7-3720QM running ArchLinux and a VMWare guest with a Xeon E5-2630 rimmomg Debian 9 (Stretch/Testing).

I made a variant that included wc_encrypt.h and called wc_AesCbcEncryptWithKey (and its Decrypt sibling, of course) and everything worked as expected there.

I hadn't realised that the extra includes were relevant... I believe I included them to start with, but I was working in the CLion IDE and may have let it run its "remove unused imports" code cleanup step. Including woflssl/options.h in before aes.h has got the above sample code working as expected.

Thanks!

P.S. In case you're curious, the longer-term project is to develop a StorageArea plugin for Orthanc that will have its image and other data files encrypted as they're written to disk and decrypted as they're retrieved.

2

(5 replies, posted in wolfCrypt)

I added another local variable as a spacer, like this:

    byte iv[] = "1234567890abcdef";
    byte spacer[32] = {};
    Aes aesEncrypt;

... and now the iv is not being overwritten.

The locations of these variables are found by counting backwards from the highest available address in the memory space, (I checked addresses using gdb), so it would appear that wc_AesSetKey(&aesEncrypt) is writing four bytes of zeroes starting four bytes past the end of the aesEncrypt struct.

This behaviour was seen in the package from the Debian Squeezy (9.0) official repositories and in Archlinux using an AUR build that was current a couple of days ago.

Hi all, this is my first post.

I've got a little project I want to use wolfcrypt for, and before getting started on the production system I just threw together a bit of proof-of-concept code. Then I got unexpected results so I added a bunch of print lines for debug purposes, and here's the code as it stands:

#include <stdio.h>
#include <wolfssl/wolfcrypt/aes.h>

size_t padLength(size_t plainLength){
    size_t numBlocks = plainLength / AES_BLOCK_SIZE;
    return (numBlocks+1) * AES_BLOCK_SIZE;
}

void printBytes(byte *array, size_t length){
    for (size_t i=0; i<length; ++i){
        printf("%02X ", array[i]);
    }
}

size_t unpadLength(byte *array, size_t length){
    return length-(array[length-1]);
}

int main() {
    int error;
    byte key[] = "1234567890abcdef01234567";
    byte iv[] = "1234567890abcdef";
    Aes aesEncrypt;
    Aes aesDecrypt;
    printf("\nIV before SetKey(Encrypt): ");
    printBytes(iv, AES_BLOCK_SIZE);
    error = wc_AesSetKey(&aesEncrypt, key, (word32)strlen((char *)key), iv, AES_ENCRYPTION);
    if (error){
        printf("\nEncrypt set key failed with error: %d\n", error);
    }
    printf("\nIV  after SetKey(Encrypt): ");
    printBytes(iv, AES_BLOCK_SIZE);
    printf("\n aesEncrypt.reg  contents: ");
    printBytes((byte *) aesEncrypt.reg, AES_BLOCK_SIZE);
    error = wc_AesSetKey(&aesDecrypt, key, (word32)strlen((char *)key), iv, AES_DECRYPTION);
    if (error){
        printf("\nDecrypt set key failed with error: %d\n", error);
    }
    printf("\nIV  after SetKey(Decrypt): ");
    printBytes(iv, AES_BLOCK_SIZE);
    printf("\n aesDecrypt.reg  contents: ");
    printBytes((byte *) aesDecrypt.reg, AES_BLOCK_SIZE);
    byte plain[] = "AAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
    size_t plainLength = sizeof(plain);
    size_t paddedLength = padLength(plainLength);
    byte padded[paddedLength];
    byte padding = (byte)(paddedLength-plainLength);
    memcpy(padded, plain, plainLength);
    for (size_t i=plainLength; i<paddedLength; ++i){
        padded[i]=padding;
    }
    byte cipher[paddedLength];
    error = wc_AesCbcEncrypt(&aesEncrypt, cipher, padded, (word32)paddedLength);
    if (error){
        printf("\nEncryption failed with error: %d\n", error);
    }
    byte plain2[paddedLength];
    error = wc_AesCbcDecrypt(&aesDecrypt, plain2, cipher, (word32)paddedLength);
    if (error){
        printf("\nDecryption failed with error: %d\n", error);
    }
    printf("\nPlain1: ");
    printBytes(plain,sizeof(plain));
    printf("\n%s\nPadded: ",plain);
    printBytes(padded,paddedLength);
    printf("\nCipher: ");
    printBytes(cipher, paddedLength);
    printf("\nPlain2: ");
    printBytes(plain2, unpadLength(plain2, paddedLength));
    printf("\n%s\n",plain2);
    return 0;
}

When I run that code, I get the following output:

IV before SetKey(Encrypt): 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66 
IV  after SetKey(Encrypt): 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66 
 aesEncrypt.reg  contents: 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66 
IV  after SetKey(Decrypt): 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66 
 aesDecrypt.reg  contents: 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66 
Plain1: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 00 
AAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
Padded: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 00 05 05 05 05 05 
Cipher: 8A D4 F6 7D 53 E1 FA 88 36 9C 83 00 D8 A5 1A 60 43 AB 87 03 FE E6 1B C0 44 DF CD 71 18 D8 D7 93 C9 E5 66 48 C9 16 12 AF 07 A7 43 AF 98 95 2D 62 AA 44 FA 04 96 CE E1 73 F1 04 30 B7 CC A9 59 75 
Plain2: 41 41 41 41 74 77 76 79 41 41 41 41 41 41 41 41 41 41 41 41 74 77 76 79 42 42 42 42 42 42 42 42 42 42 42 42 77 74 75 7A 42 42 42 42 42 42 42 42 42 42 42 42 77 74 75 7A 42 42 00 
AAAAtwvyAAAAAAAAAAAAtwvyBBBBBBBBBBBBwtuzBBBBBBBBBBBBwtuzBB

When I moved things around so the decrypt struct gets configured before the encrypt chunk and ran it again I got:

IV before SetKey(Decrypt): 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66 
IV  after SetKey(Decrypt): 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66 
 aesDecrypt.reg  contents: 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66 
IV  after SetKey(Encrypt): 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66 
 aesEncrypt.reg  contents: 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66 
Plain1: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 00 
AAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
Padded: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 00 05 05 05 05 05 
Cipher: D2 08 09 0A AB 5B 27 D4 B4 17 4D 55 BD EE 45 44 40 4C F7 92 D1 D2 7D B4 FD 9D 84 DF 67 F4 9E E6 89 60 8E 63 84 8F 72 F3 1E 46 48 8D C0 D1 DF A5 1D BC CC AA 99 EA 5F B3 DA A8 93 8C 43 05 32 9B 
Plain2: 41 41 41 41 74 77 76 79 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 00 
AAAAtwvyAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

So... AesSetKey is zeroing the second word of the IV if the last argument is AES_ENCRYPTION. Any ideas why this is happening or what I should do differently?