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]

Reply via email to