On Tuesday 30 July 2002 02:54 pm, Richard Levitte - VMS Whacker wrote:

> How could num (or n, inside AES_ctr128_encrypt() ever have a value
> that isn't between 0 (included) and AES_BLOCK_SIZE (excluded), unless
> you do something stupid with num between calls?  Make note of the
> following statement:
>
>               n = (n+1) % AES_BLOCK_SIZE;

"num" could point to a value out of that range if it is not initialized before 
the first call to AES_ctr128_encrypt().  The fix for this is to clearly 
document that the value "num" points to is both an input and an output.  
However, this range of values really has no bearing on the bug.  The bug 
exists for all non-zero values.

> That program prints "success" on my system (a Pentium running Debian
> GNU/Linux).

Yes, I apologize for that.  I just ran the program on a system other than my 
own and it printed "success".  The reason it prints "success" is that the 
stack happens to be preserved between calls to AES_ctr128_encrypt().  I have 
included a new version below which makes a call to a function which mirrors 
AES_ctr128_encrypt()'s stack usage.  This should illustrate the problem.


Matt

#include <stdio.h>
#include <string.h>
#include <openssl/aes.h>

#define KEY_LENGTH 16
#define TEXT_LENGTH 36
#define COUNTER_LENGTH 16

void mirror(const unsigned char *in, unsigned char *out,
            const unsigned long length, const AES_KEY *key,
            unsigned char *counter, unsigned int *num) {
        
        unsigned int n;
        unsigned long l=length;
        unsigned char tmp[AES_BLOCK_SIZE];
        
        memset(tmp, 0xFF, AES_BLOCK_SIZE);
}

int main(void)
{
        unsigned char key[KEY_LENGTH + 1] = "9dfe5ea4c3f84ae3";
        unsigned char plaintext1[(TEXT_LENGTH / 2) + 1] = "123456789012345678";
        unsigned char plaintext2[(TEXT_LENGTH / 2) + 1] = "876543210987654321";
        unsigned char ciphertext[TEXT_LENGTH + 1];
        unsigned char plaintext[TEXT_LENGTH + 1];
        unsigned char ecounter[COUNTER_LENGTH + 1] = "6543210987654321";
        unsigned char dcounter[COUNTER_LENGTH + 1] = "6543210987654321";
        AES_KEY k;
        int num;
        int retval;


        retval = AES_set_encrypt_key(key, strlen(key) * 8, &k);
        if (retval < 0) {
                printf("couldn't set encrypt key: %d\n", retval);
                return -1;
        }

        num = 0;
        AES_ctr128_encrypt(plaintext1, ciphertext, strlen(plaintext1), 
                           &k, ecounter, &num);

        mirror(NULL, NULL, 0, NULL, NULL, NULL);

        AES_ctr128_encrypt(plaintext2, ciphertext + strlen(plaintext1),
                           strlen(plaintext2), &k, ecounter, &num);

        num = 0;
        AES_ctr128_encrypt(ciphertext, plaintext,
                           strlen(plaintext1) + strlen(plaintext2),
                           &k, dcounter, &num);

        retval = strncmp(plaintext, plaintext1, strlen(plaintext1));
        if (retval != 0) {
                printf("error\n");
                return -1;
        }
        retval = strncmp(plaintext + strlen(plaintext1), plaintext2, 
                         strlen(plaintext2));
        if (retval != 0) {
                printf("error\n");
                return -1;
        }

        printf("success\n");

        return 0;
}

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to