There have been two or three earlier threads on the potential uninitialized reads/overflows of tmp in AES_ctr128_encrypt, as well as it fact that it cannot be used for lengths not a multiple of the AES blocksize, but it does not look like anything has been done to fix it yet.
In one of the replies it was suggested that the buffer tmp for holding the encrypted counter be moved to the key structure. Doing this would mean that an AES_KEY would no longer be constant, and could no longer be used for multiple encryptions at the same time. I believe the correct solution is simply to pass a buffer in to the function the same way num already is. Since nothing actually uses AES_ctr128_encrypt() yet according to a grep of the sources, this API change shouldn't affect existing code. Below are patches which make this simple change, and which allow me to use AES_ctr128_encrypt as a stream cipher with arbitrary lengths for in and out. I'd be interested in any discussion on this subject, as I'd like to use AES-CTR in a project I'm working on... It would be nice if some fix to it could make it in before 0.9.7. Thanks, Eric *** aes.h.orig Wed Oct 9 21:59:40 2002 --- aes.h Wed Oct 9 22:00:54 2002 *************** *** 99,105 **** unsigned char *ivec, int *num); void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, ! unsigned char *counter, unsigned int *num); #ifdef __cplusplus --- 99,105 ---- unsigned char *ivec, int *num); void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, ! unsigned char *counter, unsigned char *tmp, unsigned int *num); #ifdef __cplusplus *** aes_ctr.c.orig Wed Oct 9 21:59:51 2002 --- aes_ctr.c Wed Oct 9 22:18:54 2002 *************** *** 89,107 **** } /* The input encrypted as though 128bit counter mode is being ! * used. The extra state information to record how much of the ! * 128bit block we have used is contained in *num; */ void AES_ctr128_encrypt(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]; - - assert(in && out && key && counter && num); n = *num; while (l--) { --- 89,110 ---- } /* The input encrypted as though 128bit counter mode is being ! * used. For cases where length is not a multiple of the block ! * size, extra state information to record how much of the 128bit ! * block has been used is contained in *num and the encrypted ! * block itself is contained in *tmp. *num must be initialized to ! * zero before the first call to AES_ctr128_encrypt. */ void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, ! unsigned char *counter, unsigned char *tmp, unsigned int *num) { unsigned int n; unsigned long l=length; + assert(in && out && key && counter && tmp && num); + assert(*num < AES_BLOCK_SIZE); + n = *num; while (l--) { ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]