Search code examples
cencryptionopensslaeslibcrypto

Parameter details of OpenSSL's AES_ctr128_encrypt()


I am trying to understand the parameters of the following function in openSSL crypto library.

void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
    size_t length, const AES_KEY *key,
    unsigned char ivec[AES_BLOCK_SIZE],
    unsigned char ecount_buf[AES_BLOCK_SIZE],
    unsigned int *num);

By working through the suggestions given here I was able to figure out:

*in - is the buffer in.
*out - is the buffer out.
length - is the the length of the *in buffer.
*key - is the private key.
ivec[0-7] - is the random IV
ivec[8-15] - is the counter thats incremented for every block that's encrypted.

I am not certain about the ecount_buf and num parameters.

I see that num is set to length % AES_BLOCK_SIZE after the call returns.

Any pointers to what the ecount_buf parameter is for ?


Solution

  • If you look at the implementation code taken from here:

    /* 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, and the
     * encrypted counter is kept in ecount_buf.  Both *num and
     * ecount_buf must be initialised with zeros 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[AES_BLOCK_SIZE],
        unsigned char ecount_buf[AES_BLOCK_SIZE],
        unsigned int *num) {
    
        unsigned int n;
        unsigned long l=length;
    
        assert(in && out && key && counter && num);
        assert(*num < AES_BLOCK_SIZE);
    
        n = *num;
    
        while (l--) {
            if (n == 0) {
                AES_encrypt(counter, ecount_buf, key);
                AES_ctr128_inc(counter);
            }
            *(out++) = *(in++) ^ ecount_buf[n];
            n = (n+1) % AES_BLOCK_SIZE;
        }
    
        *num=n;
    }
    

    you can deduce that it is an intermediate buffer for holding the encrypted counter. num holds the state information (in case of subsequent calls that we might make in order to chain extra data) in a form of the number of bytes used out of the total block size.