Chengy
Chengy

Reputation: 629

Encrypted string is not the same as test vector

So I am trying to encrypt some data with the EVP-API from OpenSSL. But I am not recieving the same result as the test vectors.

This is the main function

#include <stdio.h>
#include <windows.h>
#include <openssl\aes.h>
#include <openssl\evp.h>

int main()
{

    unsigned char *to = (unsigned char*)malloc(2056);
    ZeroMemory(to,2056);
    int *tosize;
    unsigned char* key = (unsigned char*)"0000000000000000000000000000000000000000000000000000000000000000";
    unsigned char* iv = (unsigned char*)"00000000000000000000000000000000";
    unsigned char* plain = (unsigned char*)"00000000000000000000000000000000";
    to = AESEncrypt(key,iv,plain,strlen((const char*)plain));
    if (to != 0)
    {
        for (int i = 0; i < strlen((const char*)to);i++)
        {
            printf("%x02", (int*)UCHAR(to[i]));
        }

    }
}

And this is the function which I am trying to call. No errors recieved. Every call is true (no error).

 unsigned char* AESEncrypt(unsigned char* key, unsigned char*iv, unsigned char*plain, size_t plainsize)
{

EVP_CIPHER_CTX *x = (EVP_CIPHER_CTX*) malloc(sizeof(EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(x);
if (EVP_EncryptInit(x,EVP_aes_256_cbc(),key,iv))
{
    unsigned char* to = (unsigned char*) malloc(plainsize + EVP_CIPHER_CTX_block_size(x));
int tosize = 0;

if(EVP_EncryptUpdate(x,to,&tosize,plain,plainsize))
{
    if (EVP_EncryptFinal(x,to,&tosize))
    {
        return to;
    }   
  }
}

return 0;
}

This is the test vector:

KEY = 0000000000000000000000000000000000000000000000000000000000000000
IV = 00000000000000000000000000000000
PLAINTEXT = 80000000000000000000000000000000
CIPHERTEXT = ddc6bf790c15760d8d9aeb6f9a75fd4e

This is what I am recieving: CIPHERTEXT = 5a0215028e.... and it goes on. As you see it is not correct.

What could I be doing wrong?

Upvotes: 1

Views: 350

Answers (1)

WhozCraig
WhozCraig

Reputation: 66194

CAVS test vectors follow a fairly straight-forward pattern. From test to test they vary to certain degrees, but one thing is eminently consistent:

Hex Strings are BYTE representations; NOT character data

Hence your "test" is entirely wrong. You're using a key, iv, and plain text that is filled with the character '0', not the byte value 0. So obviously no wonder you're getting a different result.

For that specific test your arrays should be:

unsigned char key[64] = {0};
unsigned char iv[16] = {0};
unsigned char plain[16] = {0};

Furthermore, your size sent to your encryption function should be the byte count of your plain text. Finally, your encryption function should ideally take a target buffer AND a modifiable size as the output parameters.

int AESEncrypt256(
    unsigned char* key,      // key must be 64 bytes wide.
    unsigned char *iv,       // IV must be 16 bytes wide.
    unsigned char *src,      // source buffer to encryt
    unsigned int src_len,    // length of source buffer in bytes
    unsigned char *dst,      // target buffer to write to
    unsigned int *dst_len);  // in: size of dst, out: bytes written to dst

And code the function to match those parameters. You'll be glad you did.

CAVS tests vectors are not "text". They are bytes and should be treated as such. You need to get a handle on that now, as the Monte Carlo tests are likely going to cost you some hair if you don't.

Do yourself an enormous favor and write some code now that translates a string of hex digits into an unsigned char byte array. You'll need the same to translate back for result strings. And make these routines solid as you will be using them a lot when writing these tests.


Spoiler Alert

Test the string for an odd number of chars first. If it is odd, the first byte in your translated buffer should be based on 0c, where c is the first char in the input string. From then on (or if the number of chars is even, then from the very start) grab them two-at-a-time when converting the rest of the byte string into real bytes. This means this

123456

results in a byte array of

{ 0x12, 0x34, 0x56 }

while this:

89AB1

should be:

{0x08, 0x9A, 0xB1 }

Upvotes: 4

Related Questions